Почему auto выводится по-разному?

int main(){
    int x{};
    auto x2 = x;
    auto x3{x};

    static_assert(is_same<int, decltype(x)>::value, "decltype(x) is the same as int");
    static_assert(is_same<int, decltype(x2)>::value, "decltype(x2) is the same as int");
    static_assert(is_same<int, decltype(x3)>::value, "decltype(x3) is the same as int"); // Error here.
}

Эти коды не компилируются с помощью gcc 4.8.0. Я даже не догадываюсь о типе decltype(x3). Что это? И почему поведение отличается?

Ответ 1

#include <initializer_list>
#include <type_traits>

using namespace std;

int main(){
    int x{};
    auto x2 = x;
    auto x3{x};

    static_assert(is_same<int, decltype(x)>::value, "decltype(x) is the same as int");
    static_assert(is_same<int, decltype(x2)>::value, "decltype(x2) is the same as int");
    static_assert(is_same<std::initializer_list<int>, decltype(x3)>::value, "decltype(x3) is the same as int");
}

Это скомпилируется. x3 выводится как a std::initializer_list<int> из-за:

Пусть T - тип, который был определен для идентификатора переменной d. Получите P из T [...], если инициализатор является скобкой-init-list (8.5.4), с std::initializer_list<U>.

Ответ 2

Итак, x3 на самом деле является std::initializer_list<int>, один из способов понять это:

std::cout << typeid(x3).name() << std::endl ;

для меня у меня был следующий вывод:

St16initializer_listIiE

Поместите это через c++filt:

c++filt -t St16initializer_listIiE

Дает мне:

std::initializer_list<int>