Почему структурированные привязки 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);