Почему структурированные привязки С++ 17 не используют {}?

Я нашел исходное предложение для структурированных привязок *C++ здесь. Он предлагает способ легко связать несколько возвращаемых значений, т.е.:

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

Но теперь я вижу, что все указывают на синтаксис предложения C++17/C++1z

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

Теперь, когда я узнал, что "списки пишутся {например, это}", появляется новый синтаксис списка? Почему? В чем проблема с фигурными скобками здесь?


person towi    schedule 30.10.2016    source источник
comment
Обычно подобные причудливые изменения связаны с упрощением жизни парсеров.   -  person Yakk - Adam Nevraumont    schedule 30.10.2016
comment
Одна проблема с фигурными скобками заключается в том, что фигурные скобки до сих пор ограничивают области действия, а здесь они не будут. Напротив, вы можете думать о квадратных скобках, как в списке захвата лямбда, и это работает достаточно хорошо.   -  person Kerrek SB    schedule 30.10.2016
comment
Примечание. С++ 17 еще нет. Работа над C++17 все еще продолжается. Что в нем будет, а чего нет и в каком виде, точно не будет известно как минимум до февраля.   -  person Kerrek SB    schedule 30.10.2016
comment
У нас есть несколько комментариев NB с запросом {}, так что посмотрим...   -  person T.C.    schedule 30.10.2016
comment
Теперь, когда я узнал, что списки пишутся {вроде этого}, появляется новый синтаксис списка? Почему? Это не список. Ну, это не список значений; это последовательность имен. Это не то же самое, что список значений, так почему бы не использовать другой синтаксис?   -  person Nicol Bolas    schedule 31.10.2016
comment
Ответ Чендлера Каррута на этот вопрос: youtu.be/430o2HMODj4?t=15m50s   -  person Sebastian Wahl    schedule 30.03.2017
comment
@KerrekSB, но это неправильно, поскольку фигурные скобки использовались для других целей по крайней мере с 2011 года, когда были добавлены юниформ-инициализация и initializer_list.   -  person underscore_d    schedule 21.05.2017
comment
@underscore_d: Конечно, эти фигурные скобки также существуют в C для агрегатной инициализации. Но они никогда не вводят имена, поэтому они не имеют значения с точки зрения области видимости. (Но на самом деле это тот тип фигурных скобок, о котором я забыл в предыдущем комментарии.)   -  person Kerrek SB    schedule 21.05.2017


Ответы (5)


Это все еще обсуждается. Трудно быть уверенным, какой синтаксис будет наименее запутанным, учитывая, сколько уже используется для [] и {}.

Существует также риск того, что «наименее запутанный» и «самый простой для анализа» будут конфликтовать.

person Jon Chesterfield    schedule 30.10.2016
comment
Простите, мисс, но это лямбда constexpr в размере вашего массива или атрибут в структурированной привязке? - person Kerrek SB; 31.10.2016
comment
тогда, вероятно, ранняя реализация clang++ уже запутала нас. - person towi; 31.10.2016

Национальные органы Испании и США предложили вернуться к синтаксису {}, поскольку (P0488R0):

В предложении «структурированные привязки» изначально использовались фигурные скобки «{}» для разделения идентификаторов привязок. Эти разделители были заменены скобками «[]» в связи с утверждением, что они не создают никаких синтаксических проблем. Однако оказалось, что они вносят синтаксическую неоднозначность с атрибутами и лямбда-выражениями. В свете различных предложенных исправлений кажется, что исходный синтаксис более адекватен.

Таким образом, все еще остается возможность получить исходный синтаксис для C++17 (который, как я твердо верю, предпочитает большинство пользователей).


Обновление из этого отчет о поездке:

Первоначальное предложение для объявлений декомпозиции использовало синтаксис auto {a, b, c};, который был изменен на последней встрече на auto [a, b, c]. Это изменение было довольно спорным, и в нескольких комментариях было предложено изменить его обратно на {} (в то время как другие рекомендовали сохранить []). Существуют технические аргументы с обеих сторон (синтаксис [] может конфликтовать с атрибутами, как только вы начнете разрешать вложенные декомпозиции; синтаксис {} может конфликтовать с юниформ-инициализацией, если вы добавите концепты в смесь и разрешите использовать имя концепта вместо auto), поэтому в конце концов, это во многом дело вкуса. Разработчики clang сообщили, что они пробовали оба варианта и обнаружили, что двусмысленности легче обойти с помощью []. В конце концов, консенсуса по изменению не было, поэтому статус-кво (синтаксис []) остается.

person metalfox    schedule 03.11.2016
comment
Хотя я ни согласен, ни не согласен с желанием вернуть разделители к исходному синтаксису, мне кажется забавным, что один из NB назвал это изменение внезапным или последним, когда оно было внесено несколько раз назад. - person Mikel F; 03.11.2016
comment
@MikelF В дополнение к ES и US есть также соответствующий комментарий от GB: «Вложенные объявления декомпозиции не могут работать, поскольку они конфликтуют с синтаксисом атрибутов». - person metalfox; 04.11.2016

@SebastianWahl прокомментировал только ссылку. Я быстро подытожу содержание по ссылке.

Ответ Чендлера Каррута на этот вопрос: youtu.be/430o2HMODj4?t=15m50s

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

с auto все в порядке. Но вы также можете сделать это:

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

Итак, когда вы используете {...}, это станет

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

что плохо, потому что часть tuple<int,float,string> {a,b,c} также имеет смысл в C++ и, таким образом, будет сложной двусмысленностью, которую трудно решить.

person towi    schedule 30.03.2017

Изменение с {} на [] произошло после Джексонвилля и было сделано в ответ на комментарии с этой встречи. Это подробно описано в p0144r2, в котором говорится : «потому что он визуально более отличается от существующего синтаксиса для объявления нескольких переменных одного типа».

Похоже, что комментарии NB с просьбой изменить исходное использование {} не увеличили консенсус на встречах в ноябре 2016 года, оставив использование [] нетронутым. По крайней мере, до весенней встречи.

person Mikel F    schedule 31.10.2016
comment
В самом деле? о боже. Это? - person towi; 01.11.2016
comment
@towi это одно из тех ужасно субъективных утверждений. Мне не удалось найти ни одного документа, содержащего протокол заседания в Джексонвилле, на котором было предложено изменение, поэтому я могу только строить догадки. - person Mikel F; 01.11.2016

Что касается синтаксиса квадратных скобок, то следует отметить, что он очень похож на предложения захвата лямбда-выражений, где, аналогично, вы не указываете тип переменной, поскольку подразумевается auto. т.е.

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

Очевидно, это не одно и то же, но если вы думаете об этом как о «синтаксисе для автоматического захвата с учетом контекста», он может работать:

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