14

Diciamo che ho il seguente codice:È possibile utilizzare la sintassi di inizializzazione delle parentesi graffe C++ 11 per evitare di dichiarare costruttori banali per aggregati semplici?

#include <vector> 

struct Foo 
{ 
    int tag = 0; 
    std::function<void()> code; 
}; 

int main() 
{ 
    std::vector<Foo> v; 
} 

E ora voglio aggiungere una nuova voce di Foo al vettore con lo specifico tag e codesenza creare in modo esplicito una temporanea. Ciò significa che devo aggiungere un costruttore per Foo:

struct Foo 
{ 
    inline Foo(int t, std::function<void()> c): tag(t), code(c) {} 

    int tag = 0; 
    std::function<void()> code; 
}; 

E ora posso usare emplace_back:

v.emplace_back(0, [](){}); 

Ma quando ho dovuto farlo di nuovo - per il momento 100 - con una struttura di nuova creazione , Ho pensato: non posso usare l'inizializzatore controvento? In questo modo:

#include <vector> 

struct Foo 
{ 
    int tag = 0; 
    std::function<void()> code; 
}; 

int main() 
{ 
    std::vector<Foo> v; 
    v.push_back(Foo{ 0, [](){} }); 
} 

che mi dà un errore di compilazione (non può convertire da 'inizializzazione-list' a 'Foo'), ma spero che questo può essere fatto e ho appena ricevuto la sintassi sbagliata.

risposta

14

In C++ 11, non è possibile utilizzare un aggregata initializer con il struct perché è stato utilizzato un uguale inizializzatore per il membro non statico tag. Rimuovere la parte = 0 e funzionerà:

#include <vector> 
#include <functional> 

struct Foo 
{ 
    int tag; 
    std::function<void()> code; 
}; 

int main() 
{ 
    std::vector<Foo> v; 
    v.push_back(Foo{ 0, [](){} }); 
} 
+2

Nota questa modifica in C++ 14, dove 'Foo' è un aggregato e può essere inizializzato utilizzando l'inizializzazione di aggregazione. – chris

+1

Wow, è del tutto inaspettato. Grazie! –

+0

Grazie a @chris, ogni giorno imparo qualcosa di nuovo su C++ –

9

Secondo lo standard C++ 11, Foo non è un aggregato, la presenza del tutore o uguale-inizializzatore ne impedisce uno.

Tuttavia, this rule was changed for C++14, quindi se si compila il codice con -std=c++14 (o l'impostazione equivalente di qualunque sia il vostro compilatore è), Foo sarà un aggregato e il codice verrà compilato con successo.

Live demo

Per un compilatore C++ 11, è necessario rimuovere l'inizializzatore, che renderà Foo un aggregato, o fornire un costruttore a due argomenti.

+1

Devi aspettare Visual Studio 2015 per il supporto per C++ 14 :) –

Problemi correlati