10

Dziwię następującym błędu kompilatora:'Nadmiar elementy struct inicjator występuje błąd C++ 11 jednolity inicjalizacji

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

    T t_; 
}; 

struct S 
{ 
}; 

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

błędu jest (z brzękiem)

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 daje podobny błąd.

Spodziewam się, że wyrażenie t_{t} spróbuje skopiować konstrukt t_ z t. Ponieważ S ma niejawnie wygenerowany konstruktor kopii, nie spodziewałbym się, że to będzie problem.

Czy ktoś mógłby wyjaśnić, co tu się dzieje?

Odpowiedz

17

S może mieć niejawnie wygenerowany konstruktor kopii, ale S jest także czymś innym. An agregacja. Dlatego (prawie) każde użycie {} wykona na nim agregacyjną inicjalizację. Tak więc oczekuje się, że zawartość {} będzie wartościami dla członków agregatu. A ponieważ twój agregat jest pusty ... boom.

W kodzie szablonu należy unikać jednolitej składni inicjalizacji z dokładnie tych powodów. Dla nieznanego typu T nie możesz być pewien, co zrobi {...}.

+0

"Unikalna składnia inicjalizacji powinna być unikana z dokładnie tych powodów" ... i z wielu innych powodów, takich jak zmiana semantyki podczas modyfikowania 'S'. – ipc

+1

@ipc: Nie posunąłbym się tak daleko, ale faktem jest, że czasami może to być trudne :) –

+1

nie tak jednolita składnia inicjalizacyjna? – zahir