Видны ли локальные определения типов функций внутри лямбд C ++ 0x?

StackOverflow https://stackoverflow.com/questions/2122282

Вопрос

Я столкнулся со странной проблемой.Следующий упрощенный код воспроизводит проблему в 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 ++, доступного для его тестирования.Это какое-то странное правило в C ++ 0x или просто ошибка в компиляторе?

Исходя из приведенных выше результатов, я склоняюсь к ошибке.Хотя сбой, безусловно, является ошибкой.


На данный момент я подал два заявления сообщения об ошибках.

Все приведенные выше фрагменты кода должны быть скомпилированы.Ошибка связана с использованием разрешения области в локально определенных областях.(Замечен двид.)

И ошибка сбоя имеет отношение к этому...кто знает.:)


Обновить

В соответствии с сообщения об ошибках, они оба были исправлены в следующем выпуске Visual Studio 2010.(Хотя, похоже, это не так;Возможно, VS11.)

Это было полезно?

Решение

Начиная с n3000, 5.1.2/6,

Составной оператор лямбда-выражения выдает тело функции (8.4) оператора вызова функции , но для целей поиска имени (3.4) ... составной оператор рассматривается в контекст лямбда-выражения.

Неудивительно, что локальный тип должен быть виден.

Другие советы

Функция-локальные перечисления также не могут быть обнаружены с помощью лямбд.

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
}

На самом деле это не ответ на ваш вопрос, а просто дальнейшее изучение проблемы.Мне было интересно, есть ли у компилятора проблемы, связанные с типы объявлено во внешней области видимости, так что попробовал это сделать:

#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, бета-версия 2), но и фактически приводит к сбою компилятора с внутренней ошибкой C1001.

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

Посмотрим, как все пойдет.:)


Обновить

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

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

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

Итак, поехали.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top