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() /.
Related
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".
This question already has answers here:
Which part of the C++ standard allow to declare variable in parenthesis?
(2 answers)
Closed 2 years ago.
Is there anyone who can help explain why UseString in my following example cannot accept an lvalue as a parameter? I know a temporary String is created in my case, but I cannot explain why it has to accept an rvalue here.
#include <utility>
using namespace std;
struct String
{
String(const char* cstr)
{
}
};
struct UseString
{
UseString(const String& str)
{
}
};
int main()
{
const char* cstr = "abc";
UseString(std::move(cstr)); //Correct
UseString("abc"); // Correct
UseString(cstr); // Error but why UseString cannot accept lvalue as parameter in this case?
return 0;
}
The problem is because UseString(cstr); does not do what you think it does.
It is actually a variable declaration, not a constructor call. It is treated exactly the same as UseString cstr; And cstr was already declared earlier, hence the error.
See Which part of the C++ standard allow to declare variable in parenthesis?
Per this Live Demo:
prog.cpp: In function ‘int main()’:
prog.cpp:24:16: error: conflicting declaration ‘UseString cstr’
UseString(cstr);
^
prog.cpp:21:14: note: previous declaration as ‘const char* cstr’
const char* cstr = "abc";
^~~~
There is no way the compiler can confuse UseString(std::move(cstr)); and UseString("abc"); as variable declarations, so they are treated as calls to the constructor instead.
To solve this, you can use curly braces instead of parenthesis:
UseString{std::move(cstr)};
UseString{"abc"};
UseString{cstr};
Live Demo
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());
^~~~~
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".
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
declaring a const instance of a class
Why does C++ require a user-provided default constructor to default-construct a const object?
My program like this:
class c
{
};
int main()
{
const c a;
return 0;
}
when I compile it using g++, it prompt:
main.cpp:10:7: note: ‘const class c’ has no user-provided default constructor
Why, this is just an empty class and do not do anything, why I have to provide a user-provided constructor.
Because the language rules say so.
The constant must have its value set in the definition, as it cannot be assigned a value later. If you don't explicitly provide a value, the type must have a default constructor.
You don't have to. It's just a note, not even a warning. The rationale is that the class can't do anything useful, which is rarely intended. GCC is just checking to see if you overlooked something.