This question already has an answer here:
Most vexing parse
(1 answer)
Closed 2 years ago.
Here C() is a temporary object which should have been created with no-arg constructor and then I expected a call to move constructor. Yet none of them happened. Can someone exmplain why?
#include <iostream>
using namespace std;
class C{
public:
C(){std::cout<<"No arg\n";}
C(const C& r){std:cout<<"Copy Cons\n";}
C(C&& r){std:cout<<"Move Cons\n";}
};
int main() {
C c(C());
}
The statement C c(C()); is actually a function declaration for a function called c that returns C and takes a function (unnamed) as a parameter that returns a C and takes no parameters.
In other words, it's purely declarative and has no effect on the program.
This is an example of the most vexing parse.
Even if it we fixed that (with C c((C())) or C c{C()}) , pre-C++17 most compilers used permission granted by the language to optimise away that "extra" temporary object (and since C++17 they must do so), so at best you'd probably only see the output from a single default constructor invocation.
Related
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.
#include <iostream>
using namespace std;
class A{
public:
A(){
cout << "Class A!";}
};
int main()
{
A a();
}
the above code does not call the constructor A :: A() even though they have the same input parameters (none). however if, in the main function, I remove the parenthesis from
A a();
it calls the constructor.
so what is the difference between A a; and A a();
i believe the question here is very similar maybe even the same however if some could explain in simpler terms I would be very grateful.
Do the parentheses after the type name make a difference with new?
would declaring A a(); ever call a constructor, under any circumstances?
do parameterless constructors exist in c++, or is that the same as a default constructor?
With
A a();
you declare a as a function taking no arguments and returning an A object.
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
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
I'm pretty new to c++, i'm now trying to learn all the basics,
I know when default constructors are called, but when i tried different syntax it doesn't work like i expected.
Look at the following code:
class a;
class b();
class c(NULL);
'class' is a class i created with default constructor,
for a and c everything works well, but for b it just won't recognize the variable as a class member.
As i see it b and c are basically the same, what's wrong than?
Thanks!
Don't name your class "class", as it is a reserved name.
As for C++, if the constructor takes no parameters, you instantiate it using
Foo a; // note, if you are using c++11, you can do Foo a{};
As opposed to:
Foo b();
Which actually does something totally unexpected*, and declares a function named b that returns a Foo instance.
As for Foo c(null), it won't compile as there is no default constructor that takes an argument.
* It is referred to as "the most vexing parse", though I find that to be an exaggeration. It can certainly catch you by surprise, but just knowing that you can declare a function prototype inside a function, should be enough to remove the "vexing" aspect.
In other words int getMyInt(); is obviously a function prototype when placed outside any function definitions. However, since this is also the case when inside a function definition, int getMyInt(); doesn't do anything it wouldn't normally do... which is to define a function prototype getMyInt that returns an integer.
b is interpreted as a declaration of a function taking no arguments and returning an object of type class.
This is known as the most vexing parse. Edit: This is not the most vexing parse.
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)’