автоматический вывод типа с единым синтаксисом инициализации С++ 11 против С++ 17

Я пытался проверить вывод автоматического типа. Как Скотт Мейерс (Эффективный современный C++), так и язык программирования C++ Бьярна Страуструпа упоминают, что выполнение

auto val {10};

сделает вывод, что val имеет тип списка инициализации.

Я читал, что это было изменено в С++ 17, так что если в списке есть только один элемент, то вместо этого auto будет выводиться к типу этого элемента.

Однако я протестировал это с последними компиляторами gcc (v10) и clang (V11), явно указав стандарт С++ 11, и я не увидел ожидаемого поведения.

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

печатает d на экран

тогда как

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

выводит St16initializer_listIdE на экран.

Это то же самое независимо от того, являюсь ли я видом

gcc -std=c++11

or

gcc -std=c++17

и аналогично для clang.

Я понимаю, что это было изменено в C++17, но почему тогда я не вижу старого поведения? Или я неправильно понимаю?

Спасибо


person TCD    schedule 01.02.2021    source источник


Ответы (2)


Документ, в котором представлено это изменение для C++17 — https://wg21.link/n3922, — имеет утверждение:

Указание от EWG состоит в том, что мы считаем это дефектом C++14.

Если что-то является дефектом, это означает, что статья применяется задним числом, поэтому будущие компиляторы, компилирующие предыдущий стандарт, будут демонстрировать новое поведение. Вот почему вы не видите старого поведения.

Если вы скомпилируете с помощью более старого компилятора до того, как этот дефект был исправлен, вы увидите, что выведенный тип — std::initializer_list<double>: https://godbolt.org/z/GrnrTE . В то время как если вы измените компилятор на более новую версию (например, g++ 10.2), вы увидите, что выведенный тип будет double: https://godbolt.org/z/r5G945

person Justin    schedule 01.02.2021

С

auto A { 1.0 };

у вас есть прямая инициализация, и вы будете использовать тип вложенного выражения, чтобы вывести тип.

Это по существу эквивалентно

auto A = 1.0;

С другой стороны

auto A = { 1.0 };

является инициализация списка копирования, и при использовании в в сочетании с auto:

Специальное исключение сделано для вывода типа с использованием ключевого слова auto, которое выводит любой список инициализации в фигурных скобках как std::initializer_list в инициализации списка копирования.

person Some programmer dude    schedule 01.02.2021
comment
Хорошая информация, неправильный вопрос. Этот вопрос о том, почему компилятор, похоже, не делает этого таким образом. - person Nicol Bolas; 01.02.2021