Являются ли функции локального typedefs внутри С++ 0x lambdas?
У меня возникла странная проблема. Следующий упрощенный код воспроизводит проблему в MSVC 2010:
template <typename T>
struct dummy
{
static T foo(void) { return T(); }
};
int main(void)
{
typedef dummy<bool> dummy_type;
auto x = []{ bool b = dummy_type::foo(); };
// auto x = []{ bool b = dummy<bool>::foo(); }; // works
}
typedef
, созданный локально в функции, не кажется видимым в лямбда. Если я заменю typedef
на фактический тип, он будет работать как ожидалось.
Вот некоторые другие тестовые примеры:
// crashes the compiler, credit to Tarydon
int main(void)
{
struct dummy {};
auto x = []{ dummy d; };
}
// works as expected
int main(void)
{
typedef int integer;
auto x = []{ integer i = 0; };
}
У меня нет g++ для тестирования, прямо сейчас. Это какое-то странное правило в С++ 0x или просто ошибка в компиляторе?
Из приведенных выше результатов я склоняюсь к ошибке. Хотя авария определенно является ошибкой.
В настоящее время я зарегистрировал два отчета об ошибках.
Все фрагменты кода выше должны компилироваться. Ошибка связана с использованием разрешения области видимости на локально определенных объектах. (Пятнистый dvide.)
И ошибка сбоя связана с... кто знает.:)
Update
Согласно отчетам об ошибках , они оба исправлены для следующей версии Visual Studio 2010. (Хотя это, похоже, не так, VS11 возможно.)
Ответы
Ответ 1
Из n3000, 5.1.2/6,
Лямбда-выражения составной оператор дает функция-тело (8.4) функции вызова, но для целей поиск имени (3.4),... составная заявка рассматривается в контекст лямбда-выражения.
Неудивительно, что локальный тип должен быть видимым.
Ответ 2
Локальные переменные функции также не могут быть обнаружены lambdas.
int main()
{
enum E {A, B, C};
auto x = [](){ int a = A; };
//auto y = [](){ E a = A; }; // this will crash the compiler
}
ошибка C3493: "A" не может быть неявно зафиксирована, потому что не указан режим захвата по умолчанию
Ниже приведен рабочий стол, проблематичный - может быть, хотя.
int main()
{
enum E {A, B, C};
auto x = [=](){ int a = A; };
// typedef E F;
// auto y = [=](){ F a = A; }; // this compiles ok
}
Ответ 3
На самом деле это не ответ на ваш вопрос, а просто исследуйте проблему. Мне было интересно, есть ли у компилятора проблемы с типами, объявленными в охватывающей области, поэтому попробовал это:
#include <iostream>
template <typename Func>
void do_test(Func pFunc) {
}
template <typename T>
void test_trait(void) {
class Something { public: int foo; };
do_test ([] (T pX) {
Something A; A.foo = 12;
});
}
int main(void) {
test_trait<int> ();
}
Здесь я просто пытаюсь создать локальный тип в охватывающей области и использовать его из лямбда-функции. Это не только не компилируется (с Visual Studio 2010, Beta 2), но и фактически выдает компилятор с внутренней ошибкой C1001.
Ответ 4
Я написал два отчета об ошибках.
Мы посмотрим, как это получится.:)
Update
Обе ошибки отмечены как исправленные:
Мы ценим ваши отзывы. Эта ошибка была замечена нами ранее, и мы исправили ее в следующем выпуске. Благодарим вас за использование продукта.
Спасибо,
Ульзий Лувсанбат
Команда Windows С++
Итак, мы идем.