Pregunta

Tengo clase fenotipo con el siguiente constructor:

Phenotype(uint8 init[NUM_ITEMS]);

Me puede crear un fenotipo de esta manera:

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

Pero me sale un error al intentar 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(<brace-enclosed initializer list>)’
main.cpp:37: note: candidates are: Phenotype::Phenotype(uint8*)

El error parece indicar que hay una manera de definir un constructor que tiene un aparato ortopédico-cerrado inicializador lista. ¿Alguien sabe cómo se puede hacer esto?

¿Fue útil?

Solución

sólo se puede hacer para los agregados (arrays y ciertas clases. Contrariamente a la creencia popular, esto funciona para muchos nonpods también). Escribir un constructor que los lleva no es posible.

Desde que ha etiquetado como "C ++ 0x", entonces esto es posible sin embargo. Las palabras mágicas son "inicializador lista constructor". Esto va como

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

Sin embargo, tales inicialización por defecto construcción de la matriz y a continuación, utilizar el operador de asignación. Si tu objetivo para la velocidad y la seguridad (se producen errores en tiempo de compilación para demasiados inicializadores!), También se puede utilizar un constructor de ordinario con una plantilla de variadic.

Esto puede ser más genérico que necesitaba, aunque (a menudo una initializer_list basta por completo, especialmente para los enteros normales). Se beneficia de perfecto de reenvío, de modo que un argumento rvalue se puede mover hacia la construyó en un elemento de matriz

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   

Es una decisión difícil!

Editar Corrección, el último que trabaja demasiado, ya que no hacemos la explicit constructor, por lo que puede utilizar el constructor copia de Phenotype, se construye un objeto Phenotype temporal y copiarlo en p3 . Pero eso no es lo que realmente sería deseable que la llama a ser:)

Otros consejos

En C ++ 0x parece que se puede crear un constructor para esta. No tengo ninguna experiencia con él mismo, pero parece que se llama inicializador lista constructor .

  

Un contenedor podría implementar una inicialización del constructor-lista como esta:

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 ...
};

Se necesita usar la std :: initializer_list tipo de plantilla. Ejemplo:

#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};
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top