123 votes

Initialisation d'un tableau de membres dans l'initialiseur du constructeur

class C 
{
public:
 C() : arr({1,2,3}) //doesn't compile
{}
    /*
    C() : arr{1,2,3} //doesn't compile either
{}
    */
private:
 int arr[3];
};

Je crois que la raison en est que les tableaux peuvent être initialisé qu'avec = de la syntaxe, qui est:

int arr[3] = {1,3,4};

Questions

  1. Comment puis-je faire ce que je veux faire (c' est, initialiser un tableau dans un constructeur (pas d'affectation d'éléments dans le corps)). Est-il même possible?
  2. Le C++03 standard de dire quelque chose de spécial sur l'initialisation des agrégats (y compris les tableaux) dans ctor initialiseurs? Ou la invalidness le code ci-dessus est un corollaire de certaines autres règles?
  3. C++0x initialiseur de listes de résoudre le problème?

P. S. s'il vous Plaît ne pas mentionner les vecteurs, boost::tableaux, et leur supériorité à des tableaux, dont je suis bien conscient.

68voto

Johannes Schaub - litb Points 256113
  1. Comment puis-je faire ce que je veux faire (c'est-initialiser un tableau dans un constructeur (pas d'affectation d'éléments dans le corps)). Est-il même possible?

Oui. C'est à l'aide d'une structure qui contient un tableau. Vous dites que vous connaissez déjà, mais alors je ne comprends pas la question. De cette façon, vous ne initialiser un tableau dans le constructeur, sans affectations dans le corps. C'est ce qu' boost::array n'.

Le C++03 standard de dire quelque chose de spécial sur l'initialisation des agrégats (y compris les tableaux) dans ctor initialiseurs? Ou la invalidness le code ci-dessus est un corollaire de certaines autres règles?

Un mem-initialiseur utilise directement l'initialisation. Et les règles de la clause 8 interdire ce genre de chose. Je ne suis pas sûr de savoir exactement sur le cas suivant, mais certains compilateurs ne le permettent.

struct A {
  char foo[6];
  A():foo("hello") { } /* valid? */
};

Voir cette GCC PR pour plus de détails.

C++0x initialiseur de listes de résoudre le problème?

Oui, ils le font. Toutefois, votre syntaxe n'est pas valide, je pense. Vous devez utiliser des accolades directement à l'incendie au large de la liste d'initialisation

struct A {
  int foo[3];
  A():foo{1, 2, 3} { }
  A():foo({1, 2, 3}) { } /* invalid */
};

37voto

C++98 ne pas fournir une syntaxe directe pour rien, mais en réduction à zéro (ou pour les non-POD éléments, la valeur de l'initialisation) de la matrice. Pour que vous venez d'écrire, C(): arr() {}.

J'chose Roger Pate est erroné au sujet de la prétendue limitations de C++0x globale de l'initialisation, mais je suis trop paresseux pour le consulter ou de le vérifier, et il n'a pas d'importance, n'est ce pas? EDIT: Roger parlais de "C++03", j'ai mal lu, comme "C++0x". Désolé, Roger.

En C++98 solution de contournement pour votre code actuel est d'envelopper le tableau dans une struct et l'initialiser à partir d'une constante statique de ce type. Les données de résider quelque part de toute façon. Pied levé, il peut ressembler à ceci:

class C 
{
public:
    C() : arr( arrData ) {}

private:
     struct Arr{ int elem[3]; };
     Arr arr;
     static Arr const arrData;
};

C::Arr const C::arrData = {{1, 2, 3}};

9voto

Alexey Malistov Points 13526

Solution de contournement:

 template<class T, size_t N>
struct simple_array { // like std::array in C++0x
   T arr[N];
};


class C : private simple_array<int, 3> 
{
      static simple_array<int, 3> myarr() {
           simple_array<int, 3> arr = {1,2,3};
           return arr;
      }
public:
      C() : simple_array<int, 3>(myarr()) {}
};
 

1voto

leden Points 1674

Que diriez-vous

 ...
  C() : arr{ {1,2,3} }
{}
...
 

?

Compile bien sur g ++ 4.8

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X