2010-11-07 23 views
38

ho fenotipo classe con il seguente costruttore:Brace-racchiuso lista di inizializzazione del costruttore

Phenotype(uint8 init[NUM_ITEMS]); 

posso creare un fenotipo simile a questo:

uint8 data[] = {0,0,0,0,0}; 
Phenotype p(data); 

Ma ottengo un errore quando provo a generare uno come questo:

Phenotype p = {0,0,0,0,0}; 

uscita:

01.235.164,106 mila

L'errore sembra indicare che esiste un modo per definire un costruttore che accetta un elenco di inizializzazione racchiuso tra parentesi. Qualcuno sa come questo potrebbe essere fatto?

+0

possibile duplicato (http://stackoverflow.com/questions/3424727/can-we- pass-array-as-arguments-to-functions-by-this-syntax-under-upcoming-c0x) – kennytm

risposta

66

Può essere fatto solo per gli aggregati (array e determinate classi. Contrariamente alla credenza popolare, questo funziona anche per molti nonpod). Non è possibile scrivere un costruttore che li prenda.

Dato che lo hai taggato come "C++ 0x", questo è comunque possibile. Le parole magiche sono "costruttore inizializzatore-lista". Questo va come

Phenotype(std::initializer_list<uint8> c) { 
    assert(c.size() <= std::size(m_array)); 
    std::copy(c.begin(), c.end(), m_array); 
} 

// used like 
Phenotype p1{1, 2, 3}; 
Phenotype p2({1, 3, 2}); // works too 
Phenotype p3(1, 2, 3); // doesn't work 

Tuttavia, tale inizializzazione creerà di default l'array e quindi utilizzerà l'operatore di assegnazione. Se miri alla velocità e alla sicurezza (ricevi errori di compilazione per troppi inizializzatori!), Puoi anche usare un costruttore ordinario con un modello variadico.

Questo può essere più generico del necessario (spesso una lista di inizializzazione è sufficiente, soprattutto per numeri interi semplici). Gode ​​di inoltro perfetto, in modo che un argomento rvalue può essere costruito spostarsi in un elemento di un array

template<typename ...T> 
Phenotype(T&&...t):m_array{ std::forward<T>(t)... } { 

} 

// used like 
Phenotype p1{1, 2, 3}; 
Phenotype p2(1, 2, 3); // works too 
Phenotype p3({1, 2, 3}); // doesn't work 

E 'una scelta difficile!

Modifica correzione, l'ultima opera anche, come non abbiamo fatto il costruttore explicit, in modo che possa utilizzare il costruttore copia di Phenotype, costruire un oggetto temporaneo Phenotype e copiarlo verso p3. Ma non è quello che vorremmo fossero le chiamate :)

+0

Molto utile. Ho guardato intorno per una risposta a questo per un po 'di tempo. –

+2

Lo ha etichettato come C++ 11. Ma come mai non funziona in C++ 11? –

6

In C++ 0x sembra possibile creare un costruttore per questo. Non ho esperienza con me stesso, ma sembra che si chiami initializer list-constructor.

Un contenitore potrebbe implementare un inizializzatore-list costruttore in questo modo:

template<class E> class vector { 
public: 
    vector (std::initializer_list<E> s) // initializer-list constructor 
    { 
     reserve(s.size()); // get the right amount of space 
     uninitialized_copy(s.begin(), s.end(), elem); // initialize elements (in elem[0:s.size())) 
     sz = s.size(); // set vector size 
    } 

    // ... as before ... 
}; 
3

È necessario utilizzare lo std :: initializer_list tipo di modello. Esempio: [? Possiamo passare le matrici come argomenti a funzioni da questa sintassi, sotto imminente C++ 0x standard]

#include <iostream> 
class X { 
    public: 
     X (std::initializer_list<int> list) { 
     for (auto i = list.begin(); i != list.end(); i++) { 
       std::cout << *i << std::endl; 
      } 
     } 
}; 


int main() { 
    X x = {1,2,3,4,5}; 
} 
Problemi correlati