Приведенный здесь код написан на основе примера из раздела стандарта С++ 2011 5.1.2 "Lambda Expressions", который должен демонстрировать, как "захватываются" (captured) переменные во вложенных лямбда выражениях.
Вот этот код
#include <iostream>
int main()
{
{
int a = 1, b = 1, c = 1;
auto m1 = [ a, &b, &c ] () mutable
{
auto m2 = [ a, b, &c ] () mutable
{
std::cout << a << b << c;
a = b = c = 4;
};
a = b = c = 3;
m2();
};
a = b = c = 2;
m1();
std::cout << a << b << c;
}
}
Согласно стандарту результатом работы этого кода должен быть вывод на консоль следующей строки
123234 У кого есть интерес и желание, могут поломать голову, почему именно такой результат должен быть выведен. Это отдельная тема для разговора, которая заслуживает внимание, если хотите освоить работу лямбда-выражений. Пока лишь замечу, что увлечение включением в код вложенных лямбда выражений делает код трудно воспринимаемым, и может стать источником серьезных ошибок.
Приведенный пример не компилируется
MS VC++ 2010. При компиляции выдается серия сообщений об ошибках, по одной для каждой захваченной переменной во внутреннем лямбда выражении
m2.
Вот эти ошибки:
error C3480: `anonymous-namespace'::<lambda2>::a: передаваемая переменная в лямбда-выражении должна быть из внешней области видимости функции
error C3480: `anonymous-namespace'::<lambda2>::b: передаваемая переменная в лямбда-выражении должна быть из внешней области видимости функции
error C3480: `anonymous-namespace'::<lambda2>::c: передаваемая переменная в лямбда-выражении должна быть из внешней области видимости функции
Однако если тот же самый код компилировать с помощью
онлайнового компилятора, то он успешно компилируется и выполняется.
Надо отметить, что обработка лямбда выражений в компиляторах Майкрософт появилась задолго до принятия стандарта. Если я не ошибаюсь, они присутствовали еще в
MS VC++ 2008. Тем не менее не наблюдается, что за это время обработка лямбда выражений получила более-менее полную поддержку в
MS VC++ 2010.