web-dev-qa-db-fra.com

Initialisation par défaut de std :: array?

Avec C++ 11 std::array, ai-je la garantie que la syntaxe std::array<T, N> x; va-t-il initialiser par défaut tous les éléments du tableau?

[~ # ~] edit [~ # ~] : sinon, existe-t-il une syntaxe qui fonctionnera sur tous les tableaux (y compris les tableaux de taille zéro) initialiser tous les éléments à leur valeur par défaut?

[~ # ~] éditer [~ # ~] : on cppreference , la description du constructeur par défaut dit:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

alors la réponse peut être oui. Mais je voudrais être sûr de cela conformément à la norme ou à la norme future.

85
Vincent

Par définition, l'initialisation par défaut est l'initialisation qui survient lorsqu'aucune autre initialisation n'est spécifiée. le langage C++ vous garantit que tout objet pour lequel vous ne fournissez pas d'initialisateur explicite sera initialisé par défaut (C++ 11 §8.5/11). Cela inclut les objets de type std::array<T, N> et T[N].

Sachez qu'il existe des types pour lesquels l'initialisation par défaut n'a pas d'effet et laisse la valeur de l'objet indéterminée: tout type de type non classe ni tableau (§8.5/6). Par conséquent, un tableau d'objets initialisé par défaut avec de tels types aura une valeur indéterminée, par exemple:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

Le tableau de style c et std::array sont remplis d’entiers de valeur indéterminée, exactement comme plain_int a une valeur indéterminée.

Existe-t-il une syntaxe qui fonctionnera sur tous les tableaux (y compris les tableaux de taille zéro) pour initialiser tous les éléments à leur valeur par défaut?

J'imagine que lorsque vous dites "à leur valeur par défaut", vous voulez vraiment dire "initialiser tous les éléments sur T{} ". Ce n'est pas initialisation par défaut, c'est initialisation de valeur (8.5/7). Vous pouvez demander l'initialisation de valeur assez facilement en C++ 11 en donnant à chaque déclaration d'un initialiseur vide:

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

Ce qui initialisera tous les éléments du tableau, ce qui entraînera plain_old_int, et tous les membres des deux types de tableaux, étant initialisés à zéro.

126
Casey

Initialisation par défaut est un terme de la norme qui signifie potentiellement pas d'initialisation du tout. Vous voulez donc probablement dire initialisation à zéro.

La description sur cppreference.com est en fait un peu trompeuse. std::array Est une classe agrégée, et si le type d'élément est primitif, il s'agit de POD: "plain old data", avec une sémantique proche du langage C. Le constructeur implicitement défini de std::array< int, N > Est un trivial qui ne fait absolument rien.

Une syntaxe comme std::array< int, 3 >() ou std::array< int, 3 > x{}, Qui fournissent des valeurs nulles, ne le fait pas en appelant un constructeur. Obtenir des zéros fait partie de initialisation de valeur, spécifié en C++ 11 §8.5/8:

Initialiser en valeur un objet de type T signifie:

- si T est un type de classe (éventuellement qualifié cv) sans constructeur par défaut fourni par l'utilisateur ou supprimé, l'objet est initialisé à zéro…, et si T possède un constructeur par défaut non trivial, l'objet est initialisé par défaut;

std::array N'a pas de constructeur par défaut fourni par l'utilisateur, donc il est initialisé à zéro. Il possède un constructeur par défaut implicitement défini, mais il est trivial, il n'est donc jamais initialisé par défaut. (Mais cela ne fait aucune différence, car une initialisation triviale par définition n'a aucun effet lors de l'exécution.)

si ce n'est pas le cas, existe-t-il une syntaxe qui fonctionnera sur tous les tableaux (y compris les tableaux de taille zéro) pour initialiser tous les éléments à leur valeur par défaut?

Les tableaux de style C et std::array Sont tous deux des agrégats, et la méthode pour initialiser complètement zéro un agrégat est d'utiliser la syntaxe = {}. Cela fonctionne depuis C++ 98. Notez que les tableaux de style C ne peuvent pas avoir une étendue nulle et que sizeof (std::array< X, 0 >) n'est pas zéro.

18
Potatoswatter

Tous les deux T x[N]; et std::array<T, N> x; default - initialise chaque élément du tableau.

Par exemple, si T = std::string, chaque élément sera une chaîne vide. Si T est une classe sans constructeur par défaut, la compilation des deux fichiers échouera. Si T = int, chaque élément aura une valeur indéterminée (sauf si cette déclaration se trouve à la portée de l'espace de noms)

6
Cubbi

Tout d'abord, T x [N] initialise les éléments par défaut, bien que l'initialisation par défaut d'un type scalaire T ne fasse en réalité rien. Ce qui précède est également valable pour std :: array x. Je pense que ce dont vous avez besoin est l'initialisation de liste.

0
Lingxi