Еще один интересный баг компилятора MS VC++ 2010 при использовании лямбда-выражения в качестве аргумента функции по умолчанию.
Вот пример, демонстрирующий этот баг.
#include "stdafx.h"
#include <iostream>
void f()
{
int i = 10;
void g( int = [] { return ( sizeof( i ) ); }() );
g();
}
void g( int x )
{
std::cout << "x = " << x << std::endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
f();
return 0;
}
В этом примере внутри функции
f объявляется функция
g, у которой аргументом по умолчанию является вызов лямбда-выражения
[] { return ( sizeof( i ) ); } . В стандарте С++ 2011 говорится, что в качестве аргументов по умолчанию могут использоваться только те лямбда-выражения, которые не "захватывают" локальные переменные. В этом примере лямбда-выражение не захватывает локальную переменную
i, так как оператор
sizeof не вычисляет значение выражения, которое в нем используется. Поэтому код должен успешно компилироваться и выполняться, и результатом его выполнения будет вывод на консоль значения
sizeof( i ). И если использовать
онлайновый компилятор GCC 4.7.0, то так оно и будет.
Компилятор же MS VC++ 2010 выдает сообщения об ошибках компиляции:
цитата: |
error C3493: "i" нельзя передать неявно, поскольку не задан режим передачи по умолчанию error C2587: i: недопустимое использование локальной переменной в качестве параметра по умолчанию см. объявление "i" |
|
Я даже не знаю, стоит ли сообщать Майкрософт об этом баге, так как основная причина багов их компилятора при использовании с лямбда-выражениями связана с тем, что в Стандарте С++ 2011 внесены изменения в описание локальных классов и аргументов по умолчанию по сравнению со стандартом С++ 2003. То есть Майкрософт реализовывал поддержку лямбда-выражений в своем компиляторе VC++ 2010 на основе старого описанмия стандарта С++ без учета тех изменений, которые привнес стандарт С++ 2011.
Может быть найдется кто-нибудь, кто установил пререлизную версию компилятора Майкрософт VC++ 2011 и сможет проверить, исправлен ли этот баг или нет в новой версии компилятора, чтобы лишний раз не беспокоить Майкрософт? Если сведения о такой проверке в течении пары недель не поступят, то я сообщу Майкрософт об этом баге.