我遇到了一个奇怪的问题。以下简化代码再现了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。)
答案 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)