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

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

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

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

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

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

5 ответов

Решение

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

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

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

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

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


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

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

@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++ и, следовательно, будет сложной двусмысленностью, которую трудно решить.

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

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

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

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

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

auto [a, b] = std::make_pair(1, 2.0);
Другие вопросы по тегам