G++ не позволяет обобщенный захват объекта const по ссылке в лямбда?
Это отклоняется g++ (4.9.3 и 5.2.0), но принимается clang 3.5.0:
int main() {
const int ci = 0;
auto lambda = [ &cap = ci ]() { };
}
g++ дает error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers
. Похоже, что g++ отказывается разрешать неконстантные ссылки, за исключением, конечно, использования простого старого С++ 11 capture [&ci]
. Это кажется очень странным ограничением, возможно, ошибкой в g++?
Ответы
Ответ 1
Ваш код действителен. §5.1.2/11 идет
Сначальный захват ведет себя как , как если бы он декларировал и явно фиксировал переменную формы "auto
init-capture ;
" , декларативная область которой является соединением лямбда-выражений -statement [...]
Теперь, ясно, объявив
auto &cap = ci;
и запись cap
в порядке. То есть
int main() {
const int ci = 0;
auto &cap = ci;
auto lambda = [&cap]() { };
}
компилируется с помощью GCC. Помимо декларативной области и времени жизни cap
, нет никакого различия между этим фрагментом и вашим, поэтому GCC неверен.
Эта ошибка уже упоминалась как # 66735, с аналогичным примером:
int x = 0;
auto l = [&rx = static_cast<const int&>(x)] {};
Ответ 2
Это похоже на gcc bug: [С++ 14] lambda init-capture не работает для ссылок const, в котором говорится:
Этот код не скомпилируется:
int main() {
int x = 0;
auto l = [&rx = static_cast<const int&>(x)]() {};
}
Сообщение об ошибке:
test.cpp: 3: 14: ошибка: привязка 'const int' к ссылке типа 'int &' отбрасывает квалификаторы
auto l = [&rx = static_cast<const int&>(x)]() {
Но согласно [expr.prim.lambda]/11 rx следует зафиксировать как авто & rx = static_cast (x), то есть как const int &.
ссылки отчета об ошибках [expr.prim.lambda]/11, в котором говорится:
Выполнение init-capture ведет себя так, как будто оно объявляет и явно фиксирует переменную формы "auto init-capture"; чья декларативная область является составным выражением лямбда-выражений, за исключением того, что [...]