我想从函数返回一个lambda对象,而不将其转换为函数指针或函数对象。更具体地说,我想让它留给客户端决定是否转换为函数对象或将lambda保留为匿名函数:
template<typename F> // F may be a std::function, boost::function, or lambda object
auto func(F f) -> decltype(???) // what do I put in here?
{
return [=]()
{
return f(someParameter);
}
}
此代码无效,因为我不知道要推断的类型。一种选择可能是将lambda的主体复制到decltype
调用中。当然有更好的方法!
我想要这样做的理由是,我希望让编译器能够更智能地内联或展开lambda。这种推理有意义吗?如果是这样,为什么,何时更简单地返回std::function
?这种方法在编译时可能会变慢吗?
答案 0 :(得分:9)
在C ++ 11中,你无法做到这一点。你可以做一些接近它的事情,但不是这个。
基本上,提取一种C ++ 11 lambda的唯一方法是从类型的实例中推导出它,并且不能在未评估的上下文中命名该类型。因此函数不能返回类型取决于lambda类型的类型。 (除非在函数声明之前声明lambda,使用body,在这种情况下没有用)。您可以编写一个作为手动函数对象的仿函数,或使用std::bind
为您执行此操作。
你可以让它评估一些你也传入lambda的其他函子,但是这会变得很尴尬(特别是在C ++ 11中,这些函子要么必须键入erase,要么必须是写入的旧式函子& #34;手动&#34;作为struct
或class
)。
C ++ 1y中添加的功能之一使其变得简单:
template<typename F, typename T>
auto func(F f, T t) {
return [=]() {
return f(t);
};
}
int main() {
auto f = func( [](int x){ std::cout << x << "\n"; }, 7 );
f();
f();
}
您的编译器可能已经为此功能提供了C ++ 1y支持。
答案 1 :(得分:1)
在C ++ 11中,使用std::function<...>
在C ++ 14中,不需要decltype,所以你可以这样做:
auto f() {
return //lambda here
}
你现在可以做的一切。
Clang声称在其版本3.4中有完整的c ++ 14支持,正如目前的草案一样。 Gcc在即将推出的gcc 4.9中支持全面支持,并在gcc 4.8中支持部分支持。
答案 2 :(得分:0)
AFAIK,如果您使用lambda捕获内容,则通常不能在std::function
然后,我认为编译器无法内联返回的lambda,因为它在函数调用之前不存在。
所以你生成它,并在执行时加载它的状态并做它的事情。
如果是这样,为什么,何时更简单地返回std :: function?
<强>为什么吗
这是标准库。可能与客户一样多的自由。您可以从中提取lambda,或函数指针或函数等。
(请查看target
http://en.cppreference.com/w/cpp/utility/functional/function/target)
:当吗
如果要返回封装的函数。
它是否回答或者我是否错过了你的观点? Lambdas非常酷,但我担心我(和许多人)在学习曲线的开头高估了它们(特别是在性能方面,将它们视为自生代码巫术)