C ++ 0x和lambdas

时间:2011-11-11 21:31:11

标签: c++ lambda c++11

看看这个模板:

template <class T>
auto checkErrorCode(T& functor) -> decltype(functor()) {
    auto retCode = functor();
    // ... additional aspect-like stuff with retCode here
    return retCode;
}

应该执行在其中传递的lambda, 从lambda获取返回值,用它做一些事情, 然后将其返回给调用者。想想“方面编程”, 记录,无论如何。

即使它编译并且可以正常工作......

int foo(int param)
{
    return param>10?0:-1;
}

main()
{
    int param = 11;

    // This compiles fine
    auto action = [&](){ return foo(param); };
    checkErrorCode( action );
}

...它没有编译 - 并且发出一个难以理解的错误 - 当我直接使用内联lambda调用“checkErrorCode”时:

int foo(int param)
{
    return param>10?0:-1;
}

main()
{
    int param = 11;

    // This doesn't compile...
    checkErrorCode( [&](){ return foo(param); } );
}

有什么想法?

g ++发出这个奇怪的错误:

forSO.cpp: In function 'int main()':
forSO.cpp:24:5: error: no matching function for call to 'checkErrorCode(main()::<lambda()>)'
forSO.cpp:24:5: note: candidate is:
forSO.cpp:2:6: note: decltype (functor()) checkErrorCode(T&) [with T = main()::<lambda()>, decltype (functor()) = int]
forSO.cpp:2:6: note:   no known conversion for argument 1 from 'main()::<lambda()>' to 'main()::<lambda()>&'

在不太可能的情况下,这是编译器错误:

bash$ g++ -v
...
gcc version 4.6.2 (GCC) 

1 个答案:

答案 0 :(得分:4)

模板需要使用右值引用:

template <class T>
auto checkErrorCode(T&& functor) -> decltype(functor()) {
    auto retCode = functor();
    // ... additional aspect-like stuff with retCode here
    return retCode;
}

或者,const lvalue(const T&)。因为lambdas是临时(rvalue)函数,所以只能通过const(lvalue)引用或rvalue引用传递它们。

作为规则,除非你打算进行非常量访问(例如赋值的左侧,非常量成员函数的调用等),否则保持左值引用const。 如果你正在继续,它会变得有点复杂,因为那时你必须传递一个非const左值引用。但是你有一个显式的仿函数类,所以允许非const lvalue ref创建。在这种情况下,使用rvalue ref为lambdas更清楚,因为const lvalue ref是C ++ 98的处理方式,并且该系统的限制是创建rvalue引用的激励因素。