This question already has answers here:
C++'s most vexing parse again [duplicate]
(2 answers)
Closed 8 years ago.
This title may not be completely accurate--it's based on my best guess on what is happening and I figured it was better than "Can someone explain what is happening with this code?"
Anyway, I have this code:
class Class1 { };
class Class2
{
public:
Class2(Class1 other){}
};
void func(Class2 x){}
int main()
{
Class2 x(Class1());
func(x); //Compile Error
Class1 y1;
Class2 y2(y1);
func(y2); //Compiles fine
return 0;
}
So when I compile it, the line marked as "Compile Error" provides an error in g++ 4.9:
main.cpp: In function ‘int main()’:
main.cpp:14:10: error: could not convert ‘x’ from ‘Class2 (*)(Class1 (*)())’ to ‘Class2’
func(x);
^
clang++ 3.4.1 provides a similar error.
My best guess is that it thinks that "x" is some sort of function that returns a Class2, instead of a Class2 itself, but...why is this happening? I would think that the call to Class1 returns some anonymous Class1 which is passed into Class2's constructor.
Class2 x(Class1()); is a function declaration due to a vexing parse (google skills come in handy here).
Alternative:
Class2 x((Class1()));
Class2 x{Class1()};
This is because this line
Class2 x( Class1());
declares a function actually and not an object. This is known as vexing parse.
To avoid this issue you should write:
Class2 x((Class1()));
or
Class1 y;
Class2 x( y);
Related
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 4 years ago.
This code doesn't behave how I expect it to.
#include<iostream>
using namespace std;
class Class
{
Class()
{
cout<<"default constructor called";
}
~Class()
{
cout<<"destrutor called";
}
};
int main()
{
Class object();
}
I expected the output 'default constructor called', but I did not see anything as the output. What is the problem?
Nope. Your line Class object(); Declared a function. What you want to write is Class object;
Try it out.
You may also be interested in the most vexing parse (as others have noted). A great example is in Effective STL Item 6 on page 33. (In 12th printing, September 2009.) Specifically the example at the top of page 35 is what you did, and it explains why the parser handles it as a function declaration.
No call to constructor
Because the constructor never gets called actually.
Class object(); is interpreted as the declaration of a function object taking no argument and returning an object of Class [by value]
Try Class object;
EDIT:
As Mike noticed this is not exactly the same code as what you are feeding to the compiler. Is the constructor/destructor public or is Class a struct?
However google for C++ most vexing parse.
You can use it like this:
Class obj;
//or
Class *obj = new Class(/*constructor arguments*/);
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 4 years ago.
This code doesn't behave how I expect it to.
#include<iostream>
using namespace std;
class Class
{
Class()
{
cout<<"default constructor called";
}
~Class()
{
cout<<"destrutor called";
}
};
int main()
{
Class object();
}
I expected the output 'default constructor called', but I did not see anything as the output. What is the problem?
Nope. Your line Class object(); Declared a function. What you want to write is Class object;
Try it out.
You may also be interested in the most vexing parse (as others have noted). A great example is in Effective STL Item 6 on page 33. (In 12th printing, September 2009.) Specifically the example at the top of page 35 is what you did, and it explains why the parser handles it as a function declaration.
No call to constructor
Because the constructor never gets called actually.
Class object(); is interpreted as the declaration of a function object taking no argument and returning an object of Class [by value]
Try Class object;
EDIT:
As Mike noticed this is not exactly the same code as what you are feeding to the compiler. Is the constructor/destructor public or is Class a struct?
However google for C++ most vexing parse.
You can use it like this:
Class obj;
//or
Class *obj = new Class(/*constructor arguments*/);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Most vexing parse: why doesn't A a(()); work?
I have two classes in file1.h:
class ZoneRecord {
public:
//a lof of stuff here
};
class RegisterRecord {
public:
RegisterRecord(ZoneRecord rec); //this function register object rec in a fabric
};
And file2.cpp has:
#include "file1.h"
class MockZoneRecord: public ZoneRecord {
public:
MockZoneRecord(): ZoneRecord() {}
};
RegisterRecord mockrecord_register(MockZoneRecord());
This code compiles perfectly, except one thing. It says that mockrecord_register is a declaration of a function. But I actually wanted to create an global object of type RegisterRecord with name mockrecord_register. How to explicitly tell to compiler that this is not a function prototype, but an object?
You are experiencing the most vexing parse.
One way to solve this is to use copying, like
RegisterRecord mockrecord_register = RegisterRecord(MockZoneRecord());
Another is the use of parenthesis like in the answer by yuri kilochek.
If your compiler is C++11 compatible, you could use this construct:
RegisterRecord mockrecord_register{MockZoneRecord()};
Place parenthesis around argument:
RegisterRecord mockrecord_register((MockZoneRecord()));
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 4 years ago.
This code doesn't behave how I expect it to.
#include<iostream>
using namespace std;
class Class
{
Class()
{
cout<<"default constructor called";
}
~Class()
{
cout<<"destrutor called";
}
};
int main()
{
Class object();
}
I expected the output 'default constructor called', but I did not see anything as the output. What is the problem?
Nope. Your line Class object(); Declared a function. What you want to write is Class object;
Try it out.
You may also be interested in the most vexing parse (as others have noted). A great example is in Effective STL Item 6 on page 33. (In 12th printing, September 2009.) Specifically the example at the top of page 35 is what you did, and it explains why the parser handles it as a function declaration.
No call to constructor
Because the constructor never gets called actually.
Class object(); is interpreted as the declaration of a function object taking no argument and returning an object of Class [by value]
Try Class object;
EDIT:
As Mike noticed this is not exactly the same code as what you are feeding to the compiler. Is the constructor/destructor public or is Class a struct?
However google for C++ most vexing parse.
You can use it like this:
Class obj;
//or
Class *obj = new Class(/*constructor arguments*/);
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
Consider the following code.
Here, A a(B()) compiles even though the constructor is A(B& b);
But print(B()) does not work. But print is also declared as print(B& b);
Why this inconsistency?
#include <iostream>
using namespace std;
class B{
public:
char b;
};
class A {
public:
B b;
A(B& b);
A() { }
};
A::A(B& b) {
this->b = b;
}
void print(B& b) { }
int main(){
print(B());
A a(B());
}
It compiles because it's not creating an instance of A. It's declaring a function named a that returns an A and receives one unnamed parameter of type pointer-to-function-returning-B. Since it's just a declaration, it compiles. If you're referred to a elsewhere in the code, you'd have seen additional problems. For why that's a function declaration instead of an object definition, the term to look up is most vexing parse.
This:
A a(B());
isn't doing what you think. It is actually parsed as a function declaration. This is commonly referred to as the "most vexing parse" in C++ (there are many posts here about it, if you search for that phrase).
You should not be passing a non-constant reference to a temporary, so the print statement should not compile. If you modify that reference in print to const, it will work.
Where you are trying to call the constructor you are actually declaring a function:
A a(B());
This declares a as a function returning A and taking as parameter a function pointer returning B and taking no parameters.
Actually trying to call the constructor results in an error, as expected:
A a = A(B());
tst.cpp:32: error: no matching function for call to ‘A::A(B)’