What does A a() mean? [duplicate] - c++

This question already has an answer here:
Most vexing parse
(1 answer)
Closed 9 years ago.
Consider this code:
#include<iostream>
using namespace std;
class A
{
public:
A():age(12){}
int age;
};
int main()
{
A a();
cout << a.age << endl;
return 0;
}
When I compile it using g++, I get an error:
you can not see the member age, because a is not a class A()
Can someone explain this to me? What is A a()?

This line
A a();
declares a function named a, returning A with no arguments. (See Most vexing parse).
What you want is
A a = A(); // value-initialization
A a{}; // the same but only valid in C++11 (and currently not supported by MSVS)
or
A a; // default initialization
C++11, §8.5/10
Note: Since () is not permitted by the syntax for initializer,
X a();
is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
For your class, value-initialization == default-initialization (at least for the outcome).
See my answer here: C++: initialization of int variables by an implicit constructor for Infos on value- vs. default-initialization for POD or built-in types.

It defines a function called a that returns an object of type A. This is known as the "most vexing parse".

Related

Can anyone tell me what's wrong with the code below down? [duplicate]

This question already has an answer here:
Most vexing parse
(1 answer)
Closed 9 years ago.
Consider this code:
#include<iostream>
using namespace std;
class A
{
public:
A():age(12){}
int age;
};
int main()
{
A a();
cout << a.age << endl;
return 0;
}
When I compile it using g++, I get an error:
you can not see the member age, because a is not a class A()
Can someone explain this to me? What is A a()?
This line
A a();
declares a function named a, returning A with no arguments. (See Most vexing parse).
What you want is
A a = A(); // value-initialization
A a{}; // the same but only valid in C++11 (and currently not supported by MSVS)
or
A a; // default initialization
C++11, §8.5/10
Note: Since () is not permitted by the syntax for initializer,
X a();
is not the declaration of a value-initialized object of class X, but the declaration of a function taking no argument and returning an X.
For your class, value-initialization == default-initialization (at least for the outcome).
See my answer here: C++: initialization of int variables by an implicit constructor for Infos on value- vs. default-initialization for POD or built-in types.
It defines a function called a that returns an object of type A. This is known as the "most vexing parse".

why c++ class initialisation from another class type not throwing an error? [duplicate]

This question already has answers here:
Most vexing parse
(1 answer)
C++'s most vexing parse again [duplicate]
(2 answers)
Why does this class object declaration work?
(3 answers)
Closed 3 years ago.
I was expecting an error to be thrown by compiler for initializing a c++ type from a temporary variable of another type.
template <bool>
struct A{
A(...);
};
template <> struct A<false>{
};
class B{
};
class C{
int i;
};
int main()
{
//A a;
B b;
C c(B());
A<false> aa(B());
cout << "Hello World!!" << endl;
}
Here I have specialized class A for nontype parameter of type bool and value false, so that it has compiler generated standard constructors only, which should not accept any other type as initializing parameter.
For simplification I have used class C with same result(no error in compilation).
But if I do
C c(b);
it results in error which I expect: error: no matching function for call to ‘C::C(B&)’
You have encountered the most vexing parse. This
C c(B());
is the declaration of a function named c that returns a C object and has one parameter (not given a name, even though with optional parentheses) of type B. You have already a fix, C c(b), but note that initialization with curly braces helps, too:
C c{B{}}; // error
Note that it recent version of gcc and clang provide incredibly useful diagnostics, clang++ e.g. without any specific warnings flags remarks that
warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
C c(B());
^~~~~

'explicit' keyword in g++ has no effect for simple constructor (not copy/assignment constructor)? [duplicate]

This question already has answers here:
What does the explicit keyword mean?
(11 answers)
Closed 7 years ago.
Can anyone explain why the following code compiles? I expect it to get an error where the double constant 3.3 can not be converted to int, since I declare the constructor to be explicit.
class A
{
public:
int n;
explicit A(int _n);
};
A::A(int _n)
{
n = _n;
}
int main()
{
A a(3.3); // <== I expect this line to get an error.
return 0;
}
It works in the other way around. Let's define in addition to your code
void f(A a)
{
}
int main()
{
A a(3.3); // <== I expect this line to get an error.
f(5);
return 0;
}
Without the word explicit it would compile, with the explicit it would report an error. The keyword forbids casting from integer to A in situations like this.
explicit class_name ( params ) (1)
explicit operator type ( ) (since C++11) (2)
1) specifies that this constructor is only considered for direct initialization (including explicit conversions)
2) specifies that this user-defined conversion function is only considered for direct initialization (including explicit conversions)
In your case you are using direct initialization to construct an instance of type A by doing this:
A a(3.3);
The explicit keyword does not stop the compiler from implicitly casting your argument from a double type to an int. It stops you from doing something like this:
A a = 33;

What do parameterless constructors mean when explicitly called at declaration [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 8 years ago.
The question sounds a bit odd, but check the code sample
#include <iostream>
using namespace std;
int main() {
string a, b(), c("test");
// No problems
a = c;
// tester.cpp:9:7: error: assignment of function ‘std::string b()’
b = c;
// tester.cpp:10:7: error: invalid conversion from ‘std::string (*)() {aka std::basic_string<char> (*)()}’ to ‘char’
a = b;
// No problems
c = a;
}
You can see that it looks like b is created with the default constructor, but in fact it is not. So my question is really is, what does string b() mean?
Condensing your code to string b();, what you're doing here is declaring a prototype to a function called b that returns a string and takes no arguments.
The commas in the "compound declaration" are obfuscating this.
It's actually a function declaration. It's possible to declare local functions but not to define them. So therefore it's not possible to explicitly call the default constructor.
Classic mistake, but the error message already says it: function std::string b() /.

C++ access rvalue referenced object from non rvalue object [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 8 years ago.
This question may be sound stupid. I just want to make sure. And maybe that someone point me where this described in standard.
We cannot have rvalue referenced objects inside lvalue. Right?
struct A{int value;};
struct B{
B(A &&value) : a(std::forward<A>(value)){}
A&& a;
};
int main()
{
// allowed
B(A()).a;
// error
B b(A());
b.a;
return 0;
}
http://coliru.stacked-crooked.com/a/ea6bd617d421a8b8
B b(A()); declares a function (most vexing parse). You get a compiler error because b has no member a.
To fix the issue write B b{A()} instead.