c++ nested constructors call issue [duplicate] - c++

This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 5 years ago.
I have 2 test classes:
class B {
public:
B(int i) {
qDebug() << "B constructor ";
}
};
class A {
public:
A(B b) {
qDebug() << "A constructor ";
}
};
Now i want to create A object with B, thats what i do:
int i = 5;
A test (B(i)); //does not work
Code compiles without errors, but second line doesnt execute at all. I've made some tests, and code below works well:
int i = 5;
A test (B((int)i)); //works
A test (B(5)); //works
So, i guess compiler cant interpret 'i' as int inside B constructor call, but why?

This:
A test(B(i));
is the same as the:
A test(B i);
which is a function declaration, not a call to constructor due to a most vexing parse.
There is a rule that states (S. Meyers, "Effective Modern C++"):
anything that can be parsed as a declaration must be interpreted as
one
To avoid that use braced initialization (instead of parentheses ()) as functions can't be declared with {} braces:
A test{B(i)};
That being said there are no "nested constructors calls" in your example.

Related

classname classobject(); does not invoke any constructor [duplicate]

This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 3 years ago.
If I have a following situation:
#include <iostream>
using namespace std;
class A {
public:
A() {
cout << "Inside A" << endl;
}
};
int main() {
A a();
return 0;
}
Why is the constructor not invoked?
If something looks like a function declaration, the C++ standard requires it be treated as a function declaration.
A a(); does not default-construct an object a of type A. It declares a function a that takes no input parameters and returns an A object as output.
To default-construct a variable a, you need to drop the parenthesis:
A a;
Or, in C++11 and later, you can use curly braces instead of parenthesis:
A a{};

c++ passing a rhs object as parameter to the constructor of anther obejct [duplicate]

This question already has answers here:
My attempt at value initialization is interpreted as a function declaration, and why doesn't A a(()); solve it?
(5 answers)
Closed 5 years ago.
I have searched the internet and SO for couple of hours on this question. There are similar questions but I could not find an answer to mine. Basically I am trying to pass a rhs object as a parameter of the constructor of another class. I did not receive any errors but neither of the two class's constructors are triggered. If I break the process into two steps: creating one object first and then pass it to the other as lhs, then it works. I tried to have a copy constructor with class2 below and it dose not work either.
Below is the coding. The program runs without errors, but the console records no output.
struct class1
{
class1()
{
std::cout << "class1 constructed" << std::endl;
}
};
struct class2
{
class2()
{
std::cout << "class2 default constructed" << std::endl;
}
template <typename T>
class2(T)
{
std::cout << "class2 with template constructed" << std::endl;
}
};
int main()
{
class2 test(class1());
return 0;
}
This is a most vexing parse issue.
class2 test(class1()); is not a variable definition (as you might expect), but a function declaration, the function is named test and returns class2, takes one unnamed parameter which is a pointer to function (which takes nothing and returns class1).
You can use braces instead (since C++11). e.g.
class2 test(class1{});
class2 test(class1());
In this line
Parentheses were disambiguated as a function declaration

The meaning of Java-like default constructor in C++ [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 5 years ago.
Suppose I have the following structure:
struct A {
A() { cout << "Default ctor\n"; }
A(int) { cout << "Ctor with params\n"; }
};
And then I want to create an object. In Java I've got accustomed to use brackets when I create an object, so the first desire is to write something like that:
A a();
The code compiles, but a actually isn't an instance of A, it is something different.
So the question is: what is a and why should I omit the brackets to call the default constructor?
See the most vexing parse, what you are actually doing is declaring a function. The way to alleviate this problem is to either eliminate the () or to use the C++11 uniform initialization syntax,
A a;
A a{};
In C++, A a(); is a forward declaration for a function called a that takes no arguments, and returns an A. It does not create an instance of A using the default constructor.
In Java, there is no need for forward declarations of functions, so A a(); can be read to be equivalent to A a;
This curiousity of C++ even has a name: see https://en.wikipedia.org/wiki/Most_vexing_parse

Constructor without arguments doesn't work [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
I wonder why the constructor doesn't work/get called in the first case.
#include <iostream>
#include <typeinfo>
class Test{
public:
Test(){ std::cout << "1\n"; };
Test(int){ std::cout << "2\n"; };
};
int main()
{
Test a(); // actually doesn't call the constructor
Test b(1); // "2"
std::cout << (typeid(b).name()) << std::endl; // "4Test"
std::cout << (typeid(a).name()); // "F4TestvE"
return 0;
}
I've also found that typenames of created variables are strange. Can anybody explain such a behavior?
I use mingw gcc 4.7.2 for Windows to compile my projects
Thanks a lot.
Test a();
Oh, that's an instantiation of a, an object of type Test.
Test a();
Oh, that's a declaration for a function of no arguments that returns something of type Test.
Oh, wait...
If you instead construct a new a(), or use an (empty) initialisation list, this ambiguity is avoided.
See Herb Sutter's excellent article for more.
Test a(); is interpreted as a declaration of a function named a that takes no parameters and returns an object of type Test.
To create an object, remove the parentheses:
Test a;
remove the parenthesis after Test a();
it should be like test a;
and it will automatically trigger the constructor with no arguments

Instance of class and function return type confusion [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 10 years ago.
I cannot do this:
class A
{
public:
A()
{
}
};
A a1();
Because A a1(); looks like a function prototype.
But I can do this:
class B
{
public:
B(std::string argument)
{
std::cout << argument;
}
};
B b1("Text");
These two things are essentially the same except the compiler is able to distinguish B b1("Text"); as NOT being a function prototype, because some data is passed in the parenthesis.
Is there any reason why the brackets must be omitted for A, or is the reason because the compiler thinks it is a function definition?
That's exactly it, and it's known as most vexing parse. The reason is that if A a1(); was treated as an object declaration, you wouldn't be able to declare a function with that prototype. And you want to be able to declare a function, right?
B b1("Text"); works because it can't be treated as a function prototype, but, for example, B b(A()); can and will.