Ошибка «Избыточные элементы в инициализаторе структуры» с униформной инициализацией С++ 11

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

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

    T t_;
};

struct S
{
};

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

Ошибка (с лязгом):

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 имеет неявно сгенерированный конструктор копирования, я не ожидал, что это будет проблемой.

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


person HighCommander4    schedule 20.02.2013    source источник


Ответы (1)


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

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

person Nicol Bolas    schedule 20.02.2013
comment
uniform initialization syntax should be avoided for exactly these reasons ... и по многим другим причинам, таким как изменение семантики при изменении S. - person ipc; 21.02.2013
comment
@ipc: я бы не стал заходить так далеко, но дело в том, что иногда это может быть сложно :) - person David Rodríguez - dribeas; 21.02.2013
comment
@ Захир: Да. Некоторые из мы хотели бы это исправить, но, похоже, существует сильное противодействие самой идее унифицированной инициализации, не говоря уже о том, чтобы исправить проблему и сделать ее унифицированной. - person Nicol Bolas; 21.02.2013
comment
Для этого тоже существует основная проблема. - person Johannes Schaub - litb; 21.02.2013
comment
@JohannesSchaub-litb знаете ли вы, было ли это разрешено в C ++ 14? - person gnzlbg; 17.09.2014