C++0x and lambdas

C++0x and lambdas

本文关键字:lambdas and C++0x      更新时间:2023-10-16

看这个模板:

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) 

模板需要使用右值引用:

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是临时(右值)函数,所以只能通过const(左值)引用或右值引用来传递它们。

作为规则,保持左值引用为const,除非你计划进行非const访问(例如赋值的左侧,调用非const成员函数等)。如果你在做延续,它可能会变得更复杂,因为你必须传递一个非const左值引用。但是您将有一个显式的函函数类,因此允许非const左值的再创建。在这种情况下,对lambdas使用右值ref更清晰,因为const左值ref是c++ 98的做事方式,而该系统的限制是创建右值引用的一个激励因素。