Brace-racchiuso initializer lista costruttore
-
29-09-2019 - |
Domanda
Ho classe fenotipo con il seguente costruttore:
Phenotype(uint8 init[NUM_ITEMS]);
I in grado di creare un fenotipo simile a questo:
uint8 data[] = {0,0,0,0,0};
Phenotype p(data);
Ma io ottenere un errore quando provo a creare uno come questo:
Phenotype p = {0,0,0,0,0};
Output:
$ make
g++ -Wall -g main.cpp -std=c++0x
main.cpp: In function ‘int main(int, char**)’:
main.cpp:109: error: no matching function for call to ‘Phenotype::Phenotype(<brace-enclosed initializer list>)’
main.cpp:37: note: candidates are: Phenotype::Phenotype(uint8*)
L'errore sembra indicare che ci sia un modo per definire un costruttore che prende un tutore-racchiuso initializer lista. Qualcuno sa come questo potrebbe essere fatto?
Soluzione
Si può essere fatto solo per gli aggregati (array e alcune classi. Contrariamente alla credenza popolare, questo funziona per molti nonpods troppo). Scrivi costruttore che li porta non è possibile.
Dal momento che si contrassegnati come "C ++ 0x", allora questo è possibile però. Le parole magiche sono "initializer-list costruttore". 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 imposterà costruire la matrice e quindi utilizzare l'operatore di assegnazione. Se si mira per la velocità e la sicurezza (che si ottiene gli errori in fase di compilazione per troppi inizializzatori!), È anche possibile utilizzare un costruttore ordinario con un modello variadic.
Questo può essere più generico di quello necessario se (spesso un initializer_list completamente sufficiente, soprattutto per interi semplici). Beneficia di inoltro perfetto, in modo che un argomento rvalue può spostarsi costruita in un elemento 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 explicit
costruttore, in modo che possa utilizzare il costruttore copia di Phenotype
, la costruzione di un oggetto Phenotype
temporanea e copiarlo verso p3
. Ma questo non è ciò che realmente vorremmo le chiama ad essere:)
Altri suggerimenti
In C ++ 0x pare è possibile creare un costruttore per questo. Non ho esperienza con esso me stesso, ma sembra che si chiama initializer lista costruttore .
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 ...
};
È necessario utilizzare lo std :: initializer_list tipo di modello. Esempio:
#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};
}