Подтвердить что ты не робот

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++?

4b9b3361

Ответ 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"; чья декларативная область является составным выражением лямбда-выражений, за исключением того, что [...]