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

Являются ли функции локального 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 возможно.)

4b9b3361

Ответ 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

Я написал два отчета об ошибках.

  • Ошибка при сбое Tarydon. (Отчет)
  • Ошибка разрешения области видимости лямбды. (Отчет)

Мы посмотрим, как это получится.:)


Update

Обе ошибки отмечены как исправленные:

Мы ценим ваши отзывы. Эта ошибка была замечена нами ранее, и мы исправили ее в следующем выпуске. Благодарим вас за использование продукта.

Спасибо,
Ульзий Лувсанбат
Команда Windows С++

Итак, мы идем.