通过模板化引用传递C++ 11 lambda

Ste*_*eve 4 c++ lambda c++11

在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;
}
Run Code Online (Sandbox Code Playgroud)

打印,

A
B
Run Code Online (Sandbox Code Playgroud)

但是,如果caller定义为参考,

template<typename H>
void caller(H &h)
{
    h();
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨,

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()>]
Run Code Online (Sandbox Code Playgroud)

为什么?

这似乎打破了lambdas为函数提供值语义的想法,而且它意味着我不能编写某些内联的小函数,这有点烦人.

(这是在较新版本的gcc中修复的吗?我没有机会测试.)

编辑:我刚发现以下内容确实有效:

template<typename H>
void caller(H *h)
{
    (*h)();
}

int main()
{
    auto c = [](){ printf("A\n"); };
    caller(&c);
    caller(&([](){ printf("B\n"); }));
}
Run Code Online (Sandbox Code Playgroud)

我不认为我能够把这样的临时地址拿走.也许那种解决了这个问题,虽然很烦人要求函数的用户传入闭包的地址而不是方便的引用.

eca*_*mur 6

您试图通过非const引用传递临时.这不适用于任何类型.

通过const引用传递lambda.