10

I durch die folgenden Compiler-Fehler überrascht bin:'Excess Elemente in struct Initialisierer' Fehlern mit C++ 11 gleichmäßiger Initialisierung

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

    T t_; 
}; 

struct S 
{ 
}; 

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

Der Fehler ist (mit Klappern):

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 gibt einen ähnlichen Fehler.

Ich würde erwarten, den Ausdruck t_{t} zu versuchen, Konstrukt t_ von t zu kopieren. Da S einen implizit erzeugten Kopierkonstruktor hat, würde ich nicht erwarten, dass dies ein Problem ist.

Kann jemand erklären, was hier vor sich geht?

Antwort

17

S kann einen implizit generierten Kopierkonstruktor haben, aber S ist auch etwas anderes. Ein Aggregat. Daher wird (fast) jede Verwendung von {} die Aggregat-Initialisierung darauf durchführen. Daher wird erwartet, dass der Inhalt von {} Werte für die Mitglieder des Aggregats ist. Und da dein Aggregat leer ist ... Boom.

Im Vorlagencode sollte aus genau diesen Gründen eine einheitliche Initialisierungssyntax vermieden werden. Für einen unbekannten Typ T können Sie nicht genau wissen, was {...} tun wird.

+0

'einheitliche Initialisierung Syntax sollte genau aus diesen Gründen vermieden werden '... und aus vielen anderen Gründen wie Ändern der Semantik beim Ändern von' S'. – ipc

+1

@ipc: Ich würde nicht so weit gehen, aber die Tatsache ist, dass es manchmal schwierig sein kann :) –

+1

nicht so einheitliche Initialisierung Syntax dann? – zahir