看看这个模板:
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)
答案 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引用的激励因素。