Question

Je classe Phénotype avec le constructeur suivant:

Phenotype(uint8 init[NUM_ITEMS]);

Je peux créer un Phénotype comme ceci:

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

Mais je reçois une erreur lorsque je tente de créer un comme ceci:

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

Sortie:

$ 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'erreur semble indiquer qu'il existe un moyen de définir un constructeur qui prend un joint accolades initialiseur liste. Est-ce que quelqu'un sait comment cela pourrait se faire?

Était-ce utile?

La solution

Il ne peut être fait pour les agrégats (tableaux et certaines classes. Contrairement à la croyance populaire, cela fonctionne pour beaucoup nonpods aussi). L'écriture d'un constructeur qui les prend est impossible.

Depuis que vous avez taguée comme « C ++ 0x », alors cela est possible cependant. Les mots magiques est « constructeur initialiseur-list ». Cela va comme

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

Toutefois, cette initialisation sera par défaut construire le tableau, puis utilisez l'opérateur d'affectation. Si vous visez pour la vitesse et la sécurité (vous obtenez des erreurs lors de la compilation pour un trop grand nombre initializers!), Vous pouvez aussi utiliser un constructeur ordinaire avec un modèle variadique.

Cela peut être plus générique que nécessaire si (souvent un initializer_list suffit complètement, en particulier pour les entiers simples). Il bénéficie de la transmission parfaite, de sorte que l'argument de rvalue peut être construit déplacer dans un élément de tableau

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   

Il est un choix difficile!

Modifier Correction, le dernier fonctionne aussi, comme nous ne faisions pas le constructeur explicit, il peut donc utiliser le constructeur de copie de Phenotype, la construction d'un objet Phenotype temporaire et le copier sur p3 . Mais ce n'est pas ce que nous voulons vraiment les appels à:)

Autres conseils

En C ++ 0x il semble que vous pouvez créer un constructeur pour cela. Je n'ai aucune expérience avec moi-même, mais il semble que ça s'appelle initialiseur liste constructeur.

  

Un conteneur peut mettre en œuvre un constructeur liste d'initialiseur comme ceci:

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

Vous devez utiliser le type de modèle std :: initializer_list. Exemple:

#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};
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top