函数本地typedef在C ++ 0x lambdas中是否可见?

时间:2010-01-23 05:42:12

标签: c++ lambda c++11 compiler-bug

我遇到了一个奇怪的问题。以下简化代码再现了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似乎在lambda中不可见。如果我用实际类型替换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中的一些奇怪的规则,还是编译器中的一个错误?

从上面的结果来看,我倾向于bug。虽然崩溃肯定是一个错误。


目前,我已经提交了两份bug reports

上面的所有代码片段都应该编译。该错误与在本地定义的范围上使用范围解析有关。 (由dvide发现。)

崩溃错误与......谁知道。 :)


更新

根据bug reports,它们都已针对Visual Studio 2010的下一个版本进行了修复。(虽然情况似乎并非如此;也许是VS11。)

4 个答案:

答案 0 :(得分:9)

从n3000,5.1.2 / 6,

  

lambda表达式   复合语句产生   功能体(8.4)的功能   呼叫运营商,但用于   名称查找(3.4),...   复合声明被考虑在内   lambda表达式的上下文。

毫不奇怪,本地类型应该是可见的。

答案 1 :(得分:3)

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
}

答案 2 :(得分:2)

这不是你问题的真正答案,而是进一步探讨这个问题。我想知道编译器是否有问题涉及在封闭范围内声明的类型,所以试了一下:

#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> ();
}

这里,我只是尝试在封闭范围内创建一个本地类型,并在lambda函数中使用它。这不仅不能编译(使用Visual Studio 2010,Beta 2),但实际上它会使C1001内部错误导致编译器崩溃。

答案 3 :(得分:2)

我已经提交了两份错误报告。

我们会看到它是怎么回事。 :)


更新

这两个错误都被标记为已修复:

  

感谢您的反馈。我们之前已经看过这个错误,我们已经在下一个版本中修复了它。感谢您使用该产品。

     

谢谢,
  Ulzii Luvsanbat
  Windows C ++团队

所以我们去了。