2013-08-12 18 views
19
struct SS {int a; int s;}; 

int main() 
{ 
    vector<SS> v; 
    v.push_back(SS{1, 2}); 
} 

Il codice può essere compilato senza errori. Tuttavia, quando la struct è inizializzata in classe, ho ottenuto un errore di compilazione. Qualcuno può spiegarlo?C++ 11 errore compilazione inizializzazione struct

struct SS {int a = 0; int s = 2;}; 

Errore:

In function ‘int main()’: 
error: no matching function for call to ‘SS::SS(<brace-enclosed initializer list>)’ 
    v.push_back(SS{1, 2}); 
         ^
note: candidates are: 
note: constexpr SS::SS() 
struct SS {int a = 0; int s = 2;}; 
     ^
note: candidate expects 0 arguments, 2 provided 
note: constexpr SS::SS(const SS&) 
note: candidate expects 1 argument, 2 provided 
note: constexpr SS::SS(SS&&) 
note: candidate expects 1 argument, 2 provided 

risposta

28

In C++ 11, quando si utilizza l'inizializzazione non membro di dati static nel punto della dichiarazione come si fa qui:

struct SS {int a = 0; int s = 2;}; 

a fare la classe a non aggregato. Questo significa che non è più possibile inizializzare un'istanza in questo modo:

SS s{1,2}; 

per fare questo lavoro sintassi di inizializzazione per un non-aggregazione, si dovrà aggiungere una due-parametro del costruttore:

struct SS 
{ 
    SS(int a, int s) : a(a), s(s) {} 
    int a = 0; 
    int s = 2; 
}; 

Questo la restrizione è stata revocata in C++ 14.

Si noti che è possibile aggiungere un costruttore predefinito per la classe. La presenza di un costruttore fornito dall'utente inibisce il compilatore generato come predefinito.

Vedere la lettura correlata here.

+3

destro, mi stava per rispondere in modo simile. Può essere visto anche senza le funzionalità di C++ 11, aggiungendo un 'costruttore di dati personalizzato() {}'. – hvd

+4

C++ 14 non esclude più le classi con gli inizializzatori in classe da essere aggregati; Vedi http: // www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html – bames53

+1

@ bames53 Grazie, non lo sapevo. È una grande notizia Trovo questa particolare regola eccessivamente restrittiva. – juanchopanza

4

uso di un inizializzatore membro predefinito rende la classe/struttura un non aggregato:

§ 8.5.1 Aggregati

Un aggregato è una matrice o una classe (Clausola 9) con nessun costrutto utente fornito (12.1), , nessun iniziatore di inizializzazione per membri di dati non statici (9.2), nessun membro di dati non statici privato o protetto (Clausola 11), nessuna classe di base (Clausola 10) e nessuna funzione virtuale (10.3).

semantica differiscono per gli inerti e non aggregati:

aggregati (ad esempio, array e struct):

Initialize members/elements beginning-to-end. 

Non aggregati:

Invoke a constructor. 

v.push_back(SS{1, 2}); // Error, it tries to call SS constructor 

che significa hai bisogno di un costruttore ora:

struct SS 
{ 
    SS(int a, int s) : a(a), s(s) 
    { 
    } 
    int a = 0; 
    int s = 2; 
}; 
+0

È interessante notare che questo non è più vero in C++ 1y, ai membri aggregati è consentito disporre di parentesi graffe o equivalenti. N3690 §8.5.1/7 dice di inizializzare gli aggregati dagli elenchi braced-init: "Se nella lista ci sono meno clausole di inizializzazione * rispetto ai membri nell'aggregato, ogni membro non inizializzato esplicitamente deve essere inizializzato da il suo * inizializzatore brace-or-equal * o, se non esiste un * inizializzatore brace-or-equal *, da un elenco di inizializzazione vuoto (8.5.4). " – Casey

-7

struct SS {int a = 0, int s = 2;};

cambio il punto e virgola in virgola, forse I'am solo un

+0

anche struct stesso non compilerà – RiaD

+0

No, questo non risponde alla domanda. – soon

Problemi correlati