Reputation: 459
I know for C++11 way of initializing a vector
using auto
, actually an std::initializer_list
is initialized instead of a vector
.
However, given below piece of code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
auto x = {1, 2};
cout << typeid(x).name() << endl;
auto z = (1, 2);
cout << z << ", type: " << typeid(z).name() << endl;
return 0;
}
I don't understand:
x
returned is St16initializer_listIiE
and the type of 'z' returned is 'i', using gcc-10 compiler. Shouldn't we just return std::initializer_list
and 'int'?z
: warning: left operand of comma operator has no effect [-Wunused-value]
. Then the 2nd half of result is: 2, type: i
. How does c++11 interpret ()
-initialized type? Why is only the last element passed into z
and thus z
is still of type int
? Upvotes: 1
Views: 213
Reputation:
Why the type of x returned is St16initializer_listIiE and the type of 'z' returned is 'i', using gcc-10 compiler. Shouldn't we just return std::initializer_list and 'int'?
typeid()
won't directly give what you would expect, it just returns the specific type identification as written down in its code. If you would like to decrypt the same, pass it via c++filt
:
c++filt -t St16initializer_listIiE
It will result in what you were expecting, i.e. an:
std::initializer_list<int>
There is a warning on z: warning: left operand of comma operator has no effect [-Wunused-value]. Then the 2nd half of result is: 2, type: i. How does c++11 interpret ()-initialized type? Why is only the last element passed into z and thus z is still of type int?
( )
is an initializer holding an expression, or a list of expressions. If you were to assign that to auto
, it would select the very last item in the expression list as its type as it would be seperated by commas till the advent of the last expression, which ideally tells auto to assign its type to the last one.
For Example:
auto x = (1, 1.5L);
would result in a long.
auto x = (1, 1.5f);
would result in a float.
auto x = (1, "string");
would result in a const char pointer.
It entirely neglects the first value within the ( )
initializer, which is an int
.
Upvotes: 3
Reputation: 306
Because { 1, 2 }
is an std::initializer_list<int>
, but (1, 2)
is an expression, that expands to comma-operator (it evaluates both arguments and returns the second one as a result, so (1, 2)
is collapsed to (2)
, which is collapsed into 2
. That's the reason, why auto z = (1, 2);
evaluates into an integer initialization.
Because the result of instruction 1
is simply ignored (remember (1, 2)
calculates both expressions and throws away the result of the first one).
Upvotes: 2
Reputation: 180630
The only thing that makes an initializer list is {}
. In
auto z = (1, 2);
what you have is the comma operator which only returns that last value. So that means your code boils down to
auto z = 2;
and since 2
is an int
, z
is an int
.
Upvotes: 4