Является ли auto необязательным ключевым словом в диапазоне циклов for?

Я помню, как кто-то однажды сказал мне,

«нет необходимости в auto внутри циклов for на основе диапазона. Это не было бы двусмысленным в языке, если бы мы удалили его».

Верно ли это утверждение?
Является ли следующий код допустимым синтаксисом C++?

for (elem : range){...}  

Я предполагал, что это уже допустимый синтаксис, но когда я начал компилировать с
clang++ --std=c++1z, мне была показана следующая ошибка:

range-based for loop requires type for loop variable
 for (elem: range){

Компилятор по-прежнему распознает это как цикл for на основе диапазона, так почему же он не может также получить этот тип?


person Trevor Hickey    schedule 21.09.2015    source источник
comment
Это обсуждалось для введения в C++17. Чтобы это предложение имело хоть какой-то смысл, нужно было доказать, что синтаксис остается однозначным, что и делает цитата. Хотя я не знаю, как сейчас обстоят дела.   -  person 5gon12eder    schedule 22.09.2015
comment
@ 5gon12eder: я думаю, что это было воспринято с большим беспокойством, особенно в отношении вопроса скрытия имен (например, является ли elem уже именем в области видимости, что, если кто-то добавит его позже и т. д.   -  person Kerrek SB    schedule 22.09.2015
comment
Этот синтаксис был предложен Stephan T Lavavej для C++17, и он будет синтаксическим сахаром для for(auto&& elem : range). IIRC clang реализовал это как часть -std=c++1z, но когда предложение было отклонено, они, вероятно, превратили это в ошибку.   -  person Praetorian    schedule 22.09.2015
comment
Насколько я помню, комитет ненавидел идею объявления переменной без типа или auto, так как это недостаточно явно, точно так же, как они отвергли [](x, y) {...} (хотя [x=2](){} было принято).   -  person chris    schedule 22.09.2015
comment
Как упомянул @Praetorian, это не прошло. Посмотрите выступление Бьерна по этому поводу: youtu.be/2egL4y_VpYg?t=1h7m45s   -  person romeric    schedule 22.09.2015


Ответы (3)


В:

for (elem : range){...}  

синтаксис в настоящее время недействителен, но было предложено сделать этот синтаксис действительным, и синтаксис поддерживается в gcc 5.2 (посмотреть вживую):

#include <vector>

int main()
{
    std::vector<int> v ;

    for( elem : v )
    {
    }
}

и если мы попробуем это в режиме С++ 14, он скажет:

предупреждение: цикл for на основе диапазона без спецификатора типа доступен только с -std=c++1z или -std=gnu++1z

Так что это явно сработает и реализовано в gcc. Похоже, эта функция была удалена в gcc 6.0.

Насколько я могу судить, это было реализовано в gcc с расчетом на то, что предложение N3853: циклы For на основе диапазонов: следующее поколение будет принято, но оно было отклонено, а обновленная версия N3994 говорит:

Это обновляет N3853 (см. [1]), который предлагает синтаксис «для (элемент: диапазон)», добавляя поддержку атрибутов и отвечая на дополнительные вопросы. Пожалуйста, ознакомьтесь с исходным предложением по обоснованию этой функции, которое здесь не повторяется.

Мы видим, что он был отклонен EWG. проблема 81, и мы также можем увидеть это из протокол городской встречи. Хотя в предложении есть много вопросов, я считаю, что STL представила убедительный набор аргументов в разделе «Вопросы и ответы» предложения, и я был разочарован тем, что предложение было отклонено.

person Shafik Yaghmour    schedule 22.09.2015
comment
Из любопытства, были ли вы разочарованы отклонением бестиповых лямбда-параметров? [](x, y) {} например. - person chris; 22.09.2015
comment
@chris хорошо, проблемы, поднятые в Приложении B к N3559 кажутся мне легче принять как настоящие проблемы, но, возможно, я упускаю некоторые детали возражений против N3994. - person Shafik Yaghmour; 22.09.2015
comment
Верно, и я забыл о концепциях в лямбда-выражениях по сравнению с тем, что они менее полезны в циклах for на основе диапазона. Мне также особенно нравилось упущение типа петли. - person chris; 22.09.2015

Синтаксис требует тип для оператора диапазона для, даже если это auto. for (elem : range) {...} является синтаксической ошибкой, так что технически да, это правда, язык может указать, что это эквивалентно for (auto elem : range) {...}.

Однако здесь есть как минимум две серьезные проблемы:

Во-первых, for (T elem : range) не требует T для использования auto. Если компилятор увидит for (elem, у него еще не будет возможности узнать, является ли elem некоторым typedef из внешней области видимости или вновь объявленной переменной. Это не двусмысленно, но компиляторам немного сложно правильно обрабатывать.

Во-вторых, вы получаете вопрос о том, каким должно быть значение по умолчанию. В пользу auto можно привести законные аргументы. В пользу auto & можно привести законные аргументы. В пользу const auto & можно привести законные аргументы. Текущий подход просто позволяет программисту выбирать. Вероятно, законные аргументы (я не совсем уверен) также могут быть приведены для некоторых из тех, у кого auto заменено на decltype(auto).

person Community    schedule 21.09.2015
comment
Хорошо, что auto не лучший вариант во многих (возможно, даже в большинстве) случаях и, следовательно, не должен быть неявным значением по умолчанию. - person Ben Voigt; 22.09.2015

Это действительно вопрос к ELL...

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

person Ben Voigt    schedule 21.09.2015
comment
Я спрашиваю о правилах языка. Если это не часть языка, то я полагаю, что ответ просто нет. Но с потоком предложений и резким ростом C++ я не уверен, где я могу проверить, определено ли это уже в языке, и не нужно ли моему компилятору наверстать упущенное. - person Trevor Hickey; 22.09.2015
comment
@TrevorHickey: C++1z все еще редактируется. Вы спрашиваете о последнем черновике (на isocpp.org/std/the-standard, выше левый угол)? - person Ben Voigt; 22.09.2015
comment
Да, последний проект. Подтверждение того, что это действительно будет поддерживаться в будущем. - person Trevor Hickey; 22.09.2015
comment
@TrevorHickey: если изменение произойдет, вы найдете его в грамматической конструкции for-range-declaration. Прямо сейчас он все еще требует типа. - person Ben Voigt; 22.09.2015
comment
Хорошо, я предполагаю, что это было предложено только тогда. - person Trevor Hickey; 22.09.2015