问题描述
代码如下
#include <functional>
#include <iostream>
using namespace std;
int foo(int a){
cout<<a;
return a;
}
template<typename R,typename ...Args>
function<void()> wrapper( R f,Args&& ... args) {
function<void()> fun([&] { f(forward<Args...>(args...)); });//crash
//function<void()> fun=bind(f,forward<Args...>(args...));
return fun;
}
int main(){
auto d=wrapper(foo,1);
d();
return 0;
}
当我使用bind时,一切都很好。但是当我使用lambda时,程序崩溃了。 我想知道是否有一种方法可以通过引用捕获lambda,但可以通过值捕获文字(以提高效率)?还是应该坚持使用bind?
解决方法
function<void()> fun([&] { f(forward<Args...>(args...)); });//crash
所有这些捕获的对象f
和所有args
都是通过引用捕获的。
所有参数都是wrapper
的参数。
但是wrapper
返回时,wrapper
的所有参数都超出范围并被销毁。然后,您的lambda捕获的引用(全部都变成了悬空引用)。
当wrapper
的参数 可以 本身被引用时,我可能会在这里看到一些摆动的地方,而lambda然后捕获对原始对象,而不是wrapper
参数本身。
但是,没有什么可以保证的。
因此,这几乎保证了未定义的行为。
确实有语法可以按值捕获f
,而其他一切都可以通过引用来捕获,但这对您没有帮助。
auto d=wrapper(foo,1);
因为即使在这种情况下(即您正在使用的参数),您的参数也是一个prvalue,当wrapper
返回时,它会冒烟,将lambda留着一个空袋子,悬空参考。
除了按值捕获 一切 之外,这里没有其他现实的选择。