2010-04-10 3 views

Répondre

4

Cela va de 8.5/16 première puce à 8.5.4 liste-initialisation et de 8.5.4/3 troisième point à 8.5.1 initialisation globale puis 8.5.1/4 dit

Un tableau de taille inconnue initialisé avec un joint accolades initialiseur liste contenant n initializer-clauses, où doit être supérieur à zéro, est défini comme ayant des éléments

La seule différence si l'objet est un tableau entre = { ... } et { ... } est que le premier est appelé copie-list-initialisation et le second est appelé direct-list-initialization, donc les deux sont des sortes d'initialisation de liste. Les éléments du tableau sont copiés-initialisés à partir des éléments de la liste d'initialisation dans les deux cas.

Notez qu'il ya une différence subtile entre ces formes si le tableau a une taille et la liste est vide, auquel cas 8.5.4 seconde balle applique:

struct A { 
    explicit A(); 
}; 

A a[1]{}; // OK: explicit constructor can be used by direct initialization 
A a[1] = {}; // ill-formed: copy initialization cannot use explicit constructor 

Cette différence ne concerne pas les listes ont un contenu auquel cas la troisième balle applique à nouveau, bien que

struct A { 
    explicit A(int); 
}; 

A a[1]{0}; // ill-formed: elements are copy initialized by 8.5.1 
A a[1] = {0}; // ill-formed: same. 

T Le FCD a changé ceci par rapport au brouillon précédent, et l'initialisation avec une liste d'initialisation vide fonctionne maintenant même avec des constructeurs par défaut explicites. Cela est dû au fait que le FCD indique que les éléments sont initialisés en valeur et que l'initialisation de la valeur ne tient pas compte de l'explicite car elle ne résout pas la surcharge des constructeurs par défaut (elle ne peut pas mieux comprendre). Le brouillon précédent utilisait une résolution de surcharge normale sur les constructeurs et rejetait ainsi les constructeurs par défaut explicites lors de l'initialisation de la copie. This defect report cela a-t-il changé?

+0

Merci :) Intéressant (mais très subtil) point sur la différence btw initialisation avec une liste vide par rapport à une liste non vide. Je me demande si la symétrie serait meilleure? –

+0

Savez-vous également si: int (&& arr) [] = {1, 2, 3}; ou int (&& arr) [3] = {1,2,3} est autorisé? –

+0

@Faisal, notez que 'explicit A (int = 0);' est un constructeur par défaut explicite. Donc, ce changement pourrait affecter plus de programmes qu'on pourrait le penser en premier. Mais je pense que le comportement du FCD est plus bénéfique, puisque "explicite" ne dit pas vraiment quelque chose sur la construction par défaut, mais plus sur les conversions d'arguments :) –

0

Oui, c'est valable depuis des décennies, même en C. La taille est simplement définie sur le nombre d'éléments fournis. Je ne connais pas la référence, malheureusement.

(Bonus supplémentaire ...) Si vous avez besoin du nombre d'éléments, utilisez sizeof(x)/sizeof(*x). Il est plus sûr que de coder en dur une constante qui peut devenir invalide si vous ajoutez ou supprimez des entrées.

EDIT: Comme souligné dans les commentaires, le code en question manque un = (un fait que j'ai manqué), sans lequel il n'est pas valide dans aucune norme actuelle de C ou C++.

+5

Incorrect. Sans le signe =, il n'est valide qu'en C++ 0x (pas en C++ 03). – SoapBox