Ошибка "Исчерпывающие элементы в инициализации структуры" с равномерной инициализацией С++ 11

Я удивлен следующей ошибкой компилятора:

template <typename T>
struct A
{
    A(T t): t_{t} {}

    T t_;
};

struct S
{
};

int main()
{
    A<S> s{S{}};
}

Ошибка (с clang):

test.cpp:4:16: error: excess elements in struct initializer
    A(T t): t_{t} {}
               ^
test.cpp:15:10: note: in instantiation of member function 'A<S>::A' requested here
    A<S> s{S{}};
         ^

GCC дает аналогичную ошибку.

Я ожидаю, что выражение t_{t} попытается скопировать конструкцию t_ из t. Поскольку S имеет неявно созданный конструктор копирования, я бы не ожидал, что это будет проблемой.

Может ли кто-нибудь объяснить, что здесь происходит?

Ответ 1

S может иметь неявно созданный экземпляр копии, но S также является чем-то другим. Совокупность. Поэтому (почти) любое использование {} будет выполнять агрегатную инициализацию на нем. Поэтому ожидается, что содержимое {} будет значением для членов агрегата. А поскольку ваш агрегат пуст... бум.

В коде шаблона следует избегать единообразного синтаксиса инициализации именно по этим причинам. Для неизвестного типа T вы не можете точно знать, что будет делать {...}.