Я столкнулся с интересным случаем (по крайней мере для меня) при использовании lambdas и задавался вопросом, является ли это ошибкой компилятора или чем-то, что разрешено стандартной функцией.
Разрежьте на погоню. Пример кода:
const int controlValue = 5;
std::vector<int> vect{ 0, 1, 2, 3 };
const auto result = std::any_of(vect.begin(), vect.end(), [](const int& item)
{
return item == controlValue;
});
Обратите внимание, что переменная controlValue
не записывается в выражение лямбда.
Кроме того, в cppreference для лямбда-выражений указано, что [] - captures nothing
Использование VS2015 для компиляции приведенного выше кода дает ошибку, которая не удивительна:
error C3493: 'controlValue' cannot be implicitly captured because no default capture mode has been specified
Однако при использовании MinGW с gcc 4.8.2 один и тот же пример компилируется и работает. Некоторые онлайн-компиляторы, включая gcc 5.4.0, clang 3.8.0, дают аналогичный результат.
Когда controlValue
теряет свой const
, тогда все проверенные компиляторы дают ошибку, все ожидают (что переменная не захвачена, что хорошо).
Какой из компиляторов является стандартным в этом случае? Означает ли это, что для константных переменных здесь используются некоторые оптимизации или другие "хаки"? Может быть, что-то захватывается неявно? Может ли кто-нибудь объяснить ситуацию, происходящую здесь?
EDIT:
Некоторые отметили, что этот вопрос является дубликатом Lambda capture constexpr object. Хотя ответ может быть несколько связанным (указывает на случай использования odr), возникает вопрос об ошибке, возникающей при захвате по ref. Тема здесь совсем другая и фокусируется на том, чтобы не фиксировать явно переменную вообще (хотя использовать ее в теле лямбда).
Просматривая больше вопросов, связанных с лямбдой, если кто-то заинтересован, я бы указал на Использование lambda capture constexpr как измерение массива, который (как указано в @Barry) предлагает ошибку VS2015 и показывает, что установка переменной controlValue
в примере здесь на static
исправляет компиляцию под VS2015.