简体   繁体   中英

auto type deduction with uniform initialisation syntax c++11 vs c++17

I was trying to test auto type deduction. Both Scott Meyers (Effective modern C++) and Bjarne Stroustrup's C++ Programming Language mention that doing

auto val {10};

will deduce val to be of type "initialisation list".

I read that this was changed in C++17 so that if there is only one element in the list, then auto will deduce to a type of that element instead.

However, I tested this with recent gcc (v10) and clang (V11) compilers by explicitly specifying the C++11 standard and I didn't see the behaviour expected

auto A {1.0};
std::cout << typeid(A).name();

prints "d" to screen

whereas

auto A={1.0};
std::cout << typeid(A).name();

prints "St16initializer_listIdE" to screen.

This is the same regardless of whether I specity

gcc -std=c++11

or

gcc -std=c++17

and similarly for clang.

I understand that it was changed in C++17, but why then do I not see the "old" behaviour? Or am I misunderstanding?

Thanks

The paper that introduced this change for C++17— https://wg21.link/n3922 —has the statement:

Direction from EWG is that we consider this a defect in C++14.

If something is a defect, that means that the paper is retroactively applied, so future compilers compiling for a previous standard will exhibit the new behavior. This is why you don't see the old behavior.

If you compile with an older compiler from before this defect was fixed, you can see that the deduced type is std::initializer_list<double> : https://godbolt.org/z/GrnrTE . Whereas if you change the compiler to a newer version (eg g++ 10.2), you can see that the deduced type is double : https://godbolt.org/z/r5G945

With

auto A { 1.0 };

you have direct initialization , and will use the type of the enclosed expression to deduce the type.

It's essentially equivalent to

auto A = 1.0;

On the other hand

auto A = { 1.0 };

is copy list initialization , and when used in conjunction with auto :

A special exception is made for type deduction using the keyword auto , which deduces any braced-init-list as std::initializer_list in copy-list-initialization.

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