Constructor de listas de inicializadores incluidos

Tengo un fenotipo de clase con el siguiente constructor:

Phenotype(uint8 init[NUM_ITEMS]); 

Puedo crear un fenotipo como este:

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

Pero me sale un error cuando bash crear uno como este:

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

Salida:

 $ 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()' main.cpp:37: note: candidates are: Phenotype::Phenotype(uint8*) 

El error parece indicar que hay una manera de definir un constructor que toma una lista de inicializadores incluidos en llaves. ¿Alguien sabe cómo se podría hacer esto?

Solo se puede hacer para agregados (matrices y ciertas clases. Contrariamente a la creencia popular, esto también funciona para muchos nopod). Escribir un constructor que los tome no es posible.

Dado que lo etiquetó como “C ++ 0x”, entonces esto es posible. Las palabras mágicas son “constructor inicializador-lista”. Esto es como

 Phenotype(std::initializer_list 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 

Sin embargo, dicha inicialización construirá la matriz por defecto y luego usará el operador de asignación. Si busca velocidad y seguridad (¡obtiene errores de tiempo de comstackción para demasiados inicializadores!), También puede usar un constructor ordinario con una plantilla variadica.

Sin embargo, esto puede ser más genérico de lo necesario (a menudo una initializer_list es completamente suficiente, especialmente para enteros simples). Se beneficia de un reenvío perfecto, por lo que un argumento de valor razonable puede moverse construido en un elemento de matriz

 template Phenotype(T&&...t):m_array{ std::forward(t)... } { } // used like Phenotype p1{1, 2, 3}; Phenotype p2(1, 2, 3); // works too Phenotype p3({1, 2, 3}); // doesn't work 

¡Es una elección difícil!

Corrección de edición , la última también funciona, ya que no hicimos que el constructor sea explicit , por lo que puede usar el constructor de copia de Phenotype , construir un objeto Phenotype temporal y copiarlo en p3 . Pero eso no es lo que realmente queremos que sean las llamadas 🙂

En C ++ 0x parece que puedes crear un constructor para esto. No tengo experiencia con esto, pero parece que se llama inicializador list-constructor .

Un contenedor puede implementar un constructor de listas de inicialización como este:

 template class vector { public: vector (std::initializer_list 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 ... }; 

Debe usar el tipo de plantilla std :: initializer_list. Ejemplo:

 #include  class X { public: X (std::initializer_list list) { for (auto i = list.begin(); i != list.end(); i++) { std::cout < < *i << std::endl; } } }; int main () { X x = {1,2,3,4,5}; }