在 gcc 4.5 中,以下代码编译并按预期工作-std=c++0x
,
#include <stdio.h>
template<typename H>
void caller(H h)
{
h();
}
int main()
{
auto c = [](){ printf("A\n"); };
caller(c);
caller([](){ printf("B\n"); });
return 0;
}
印刷,
A
B
但是,如果caller
定义为引用,
template<typename H>
void caller(H &h)
{
h();
}
编译器抱怨,
test.cpp: In function ‘int main()’:
test.cpp:61:34: error: no matching function for call to ‘caller(main()::<lambda()>)’
test.cpp:52:6: note: candidate is: void caller(H&) [with H = main()::<lambda()>]
为什么?
这似乎打破了 lambda 为函数提供值语义的想法,但此外这意味着我不能内联编写某些小函数,这有点烦人。
(这在较新版本的 gcc 中是否已修复?我还没有机会测试。)
编辑:我刚刚发现以下实际上有效:
template<typename H>
void caller(H *h)
{
(*h)();
}
int main()
{
auto c = [](){ printf("A\n"); };
caller(&c);
caller(&([](){ printf("B\n"); }));
}
我没想到我能拿这样一个临时的地址。也许这样可以解决问题,尽管要求函数的用户传入闭包的地址而不是方便的引用很烦人。