简体   繁体   中英

C++11: how does auto deal with () initializer?

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:

  1. 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'?
  2. 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 ?

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, ie 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 .

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 .

  1. 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.

  2. Because the result of instruction 1 is simply ignored (remember (1, 2) calculates both expressions and throws away the result of the first one).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM