Do the following four different syntax do the same thing when initializing a constant data member, of type int for example, in C++ 11? If not, what is the difference?
{
const int a = 5; //usual initialization, "=" is not assignment operator here it is an initialization operator.
}
{
const int a(5); //calling the constructor function directly
}
{
const int a = {5}; //similar to initializing an array
}
{
const int a{5}; //it should work, but visual studio does not recognizing it
}
Why is the fourth one not recognized by Visual Studio as a valid statement?
They are all valid and the same in Visual Studio 2013 (the last one is not valid in VS2012 as @remyabel suggested).
The two {...} syntaxes can differ from the others in what constructor is called for a type, but the type int uses no constructor.
They will differ when constructing a class that accepts a std::initializer_list<T>.
Take, for example, this constructor that has - in some form - always been a part of std::vector
explicit vector( size_type count ... );
And this one that was added in C++11
vector( std::initializer_list<T> init, const Allocator& alloc = Allocator() );
Here, vector<int>(5) will call the first constructor and make a vector size 5.
And vector<int>{5} will call the second and make a vector of a single 5.
In C++03 these are equivalent
const int a = 3;
const int a(3);
In C++11 the uniform initialization syntax was introduced and thus
const int a{3};
const int a = {3};
are allowed and are equivalent. However, the first two and the second two are NOT equivalent in all cases. {} doesn't allow narrowing. For example
int abc = {12.3f};
int xyz(12.3f);
Here's what GCC says
error: type 'float' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
int abc = {12.3f}; ^~~~~warning: implicit conversion from 'float' to 'int' changes value from 12.3 to 12 [-Wliteral-conversion]
int abc = {12.3f}; ~^~~~~
So the former begot an error, while the latter, just a warning.
Caveats in the uniform initialization syntax: If a was an object of a type accepting std::initializer_list, then const MyClass a = { 1 } would mean you're using that constructor and not the constructor taking a single int even if it was available (explained in Drew's anwer); If you want to choose the other constructor, then you've to use the () syntax. If a was an array, then you're using aggregate initialization.
See here for various initialization options available in C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With