web-dev-qa-db-fra.com

Pourquoi les liaisons structurées C ++ 17 n'utilisent-elles pas {}?

J'ai trouvé la proposition d'origine pour les liaisons structurées * C++ ici . Il propose un moyen de lier facilement plusieurs valeurs de retour, à savoir:

auto {a, b} = minmax(data);

Mais maintenant, je vois que tout le monde pointe vers la syntaxe de proposition C++ 17/C++ 1z de

auto [a, b] = minmax(data);

Maintenant que j'ai appris "les listes sont écrites {comme ça}", il y a une nouvelle liste de syntaxe? Pourquoi? Quel est le problème avec les accolades ici?

51
towi

C'est toujours en discussion. Il est difficile d'être certain de la syntaxe qui sera le moins déroutante étant donné le nombre d'utilisations déjà existantes de [] et {}.

Il y a aussi le risque que "le moins déroutant" et "le plus facile à analyser" soient en conflit.

21
Jon Chesterfield

Les organismes nationaux d'Espagne et des États-Unis ont proposé de revenir à la syntaxe {} Car ( P0488R ):

La proposition de "liaisons structurées" utilisait à l'origine des accolades "{}" pour délimiter les identificateurs de liaison. Ces délimiteurs ont été remplacés par des crochets "[]" sous l’affirmation qu’ils n’ont introduit aucun problème syntaxique. Cependant, ils se sont avérés introduire une ambiguïté syntaxique avec les attributs et les lambdas. À la lumière des diverses corrections suggérées, il semble que la syntaxe d'origine soit plus adéquate.

Par conséquent, il reste encore la possibilité de finir par avoir la syntaxe d'origine pour C++ 17 (qui, je crois fortement, est préférée par la plupart des utilisateurs).


Mise à jour de cette rapport de voyage :

La proposition d'origine pour les déclarations de décomposition utilisait la syntaxe auto {a, b, c}; Qui a été modifiée lors de la dernière réunion en auto [a, b, c]. Ce changement a été assez controversé et plusieurs commentaires ont demandé de le ramener à {} (Tandis que d'autres ont encouragé le maintien de []). Il existe des arguments techniques des deux côtés (la syntaxe [] Peut entrer en conflit avec les attributs une fois que vous commencez à autoriser les décompositions imbriquées; la syntaxe {} Peut entrer en conflit avec une initialisation uniforme si vous lancez Concepts dans le mélange et autorisez l'utilisation de un concept-nom au lieu de auto), donc en fin de compte c'est en grande partie une question de goût. Les implémenteurs de clang ont rapporté qu'ils avaient essayé les deux et trouvé les ambiguïtés plus faciles à contourner avec []. À la fin, il n'y avait pas de consensus pour un changement, donc le statu quo (syntaxe []) Demeure.

21
metalfox

@SebastianWahl n'a commenté qu'avec un lien. Je vais résumer rapidement le contenu derrière le lien.

Réponse de Chandler Carruth à cette question: youtu.be/430o2HMODj4?t=15m50s

auto [a,b,c] = f();

est ok avec auto. Mais vous pouvez aussi le faire:

Tuple<int,float,string> [a,b,c] = f();

Ainsi, lorsque vous utilisez {...} cela deviendrait

Tuple<int,float,string> {a,b,c} = f();  //<<< not C++17

ce qui est mauvais, car la pièce Tuple<int,float,string> {a,b,c} a également un sens en C++ et serait donc une ambiguïté difficile, difficile à résoudre.

13
towi

Le changement de {} à [] s'est produit après Jacksonville et a été fait en réponse aux commentaires de cette réunion. Ceci est détaillé dans p0144r2 , qui déclare: "car il est plus distinct visuellement de la syntaxe existante pour déclarer plusieurs variables du même type."

Il semble que les commentaires NB demandant une modification de l'utilisation d'origine de {} n'ont pas augmenté le consensus lors des réunions de novembre 2016, laissant l'utilisation [] intacte. Du moins jusqu'à la réunion de printemps.

10
Mikel F

Une chose à dire pour la syntaxe des crochets est qu'elle ressemble étroitement aux clauses de capture lambda, où, de même, vous ne spécifiez pas le type de variable, car auto est implicite. C'est à dire.

auto func = [a, b] {}
auto func = [a=1, b=2.0] {}

Ce n'est évidemment pas exactement la même chose, mais quand on y pense comme "syntaxe pour la capture automatique en donnant un sens au contexte", cela peut fonctionner:

auto [a, b] = std::make_pair(1, 2.0);
3
Yam Marcovic