4

在 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"); }));
}

我没想到我能拿这样一个临时的地址。也许这样可以解决问题,尽管要求函数的用户传入闭包的地址而不是方便的引用很烦人。

4

1 回答 1

6

您正在尝试通过非常量引用传递一个临时值。这对任何类型都不起作用。

改为通过 const 引用传递 lambda。

于 2012-09-06T17:08:37.517 回答