This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Closed 6 years ago.
Today when I read C++ Primer ,it said in-class initializer can't use () I have searched on Stackoverflow and find a similar question here.And the accepted answer say:the reason might be that there is a ambiguous between declaration of a member function and definition of a member of type.But I am not complete agree with him.I try the following code:
struct Sales_data
{
int i(5); //this line can't be regard as a function
};
But the compiler still complain.Who can tell me why.\
compiler:clang++ version:3-4
It is disallowed by the language. The reason is that there would be cases where it couldn't be disambiguated from a function declaration:
struct foo
{
int bar();
};
So instead of replicating the whole most vexing parse fiasco by allowing () to work sometimes, it is outright disallowed.
Related
This question already has answers here:
Different ways of initializing an object in c++
(1 answer)
What's the difference between parentheses and braces in c++ when constructing objects
(1 answer)
Closed last year.
I have a question on constructor initializer list as follows :
while specifying the initial values of members, initial values are written in ()- parenthesis according to C++ Primer book (author - Stanley Lippman). However, I have also seen {} being used to specify initial values (please refer to link - https://en.cppreference.com/w/cpp/language/constructor)
can someone explain when to use () - parenthesis and when to use {} - curly braces
thanks and regards,
-sunil puranik
According to Scott meyors Effective Modern C++, Item 7, you should basically be using {} wherever you can in the initializer list. If you are initialising a type that takes a std::initializer_list then you will need to think about it a bit more. But outside of std::vector and templates, you should basically always be using {} to construct. Why? From Scott Meyors:
Braced initialization is the most widely usable initialization syntax, it prevents
narrowing conversions, and it’s immune to C++’s most vexing parse.
Using T x{}; where T is some type, is called zero initialization.
Parenthesis () is Pre-C++11 while braces {} is from C++11 and onwards(like c++11, c++14, etc). This is just one of the many differences between the two.
For example,
Pre C++11
class MyVector
{
int x;
MyVector(): x()
{
}
};
C++11
From C++11 and onwards, you can use {} instead as shown below:
class MyVector
{
int x;
MyVector(): x{}
{
}
};
In the context of constructor initializer list(which is what your question is about) they are used to ensure proper initialization of non-static data members of a class template as explained here.
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:
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 answers here:
Should the trailing return type syntax style become the default for new C++11 programs? [closed]
(4 answers)
Closed 8 years ago.
Having looked at a few online documents on C++14, I found the following syntax for defining a function in C++14 that uses trailing return types:
auto myFunc() -> int {}
my question is, other then using this way for using decltype in the argument and some other scenarios, is there a difference or any benefit for using the above syntax for bog standard functions like:
int myFunc() {}
Argument for : coherence.
This way you don't have the freak function needing a trailing return type standing out.
Argument against : wow that's ugly.[pers. opinion]
Semantic difference : none.
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".