Кажется, что GCC неправильно отображает глобальные переменные по ссылке в лямбда-функциях, даже если они указаны как "захват по значению". Этот код будет компилировать и печатать "a = 9":
#include <iostream>
int a = 10;
int main()
{
[=]() { a = 9; } ();
std::cout << "a = " << a << std::endl;
return 0;
}
Пока этот код не будет компилироваться:
#include <iostream>
int main()
{
int a = 10;
[=]() { a = 9; } (); // error: assignment of member 'main()::<lambda()>::a' in read-only object
std::cout << "a = " << a << std::endl;
return 0;
}
Но явно фиксируя глобальное значение по значению, а затем присваивая ему, появляется ошибка:
#include <iostream>
int a = 10;
int main()
{
[a]() { a = 9; } (); // assigment of read-only object
std::cout << "a = " << a << std::endl;
return 0;
}
Я уверен, что ошибка - правильное поведение - почему неявный захват обходит эту ошибку? Я просто изучаю новые возможности С++ 11 и случайно написал первый фрагмент кода (не понимая, что это должна быть ошибка), и затем был удивлен, когда изменения в том, что я предположил, были локальной переменной, повлияли на глобальную.
Так как ошибка должна быть назначена переменной захваченного значения в лямбда, GCC предположительно использует ссылку на переменную для целей оптимизации, по крайней мере в этом случае, и не обнаруживает ошибочное назначение.