我最近开了this次讨论,其中出现了以下问题。这个问题是一种持续的讨论。这是代码:
#include <iostream>
#include <functional>
using namespace std;
std::function<int(void)> mylambda(int starter){
return [starter]() mutable {
return ++starter;
};
}
void tester_wrapper(const std::function<int(void)>& cb, int counter){
if (counter == 10)
return;
else{
cout << cb() << endl;
tester_wrapper(cb, counter + 1);
}
}
void tester(const std::function<int(void)>& cb){
tester_wrapper(cb, 0);
}
int main()
{
auto getNum = mylambda(1);
tester(getNum);
tester(getNum);
}
在这种情况下,代码执行我的预期,更具体地说,它打印从2到21的所有数字。但是,如果我的main
函数是这样的:
int main()
{
auto getNum = ([](int starter) {
return [starter]() mutable {
return ++starter;
};
})(1);
tester(getNum);
tester(getNum);
}
然后输出将是重复两次的2到11的数字。即使两段代码之间的唯一区别在于mylambda
函数的定义位置和方式,我也无法解释自己为什么产生这个输出。
答案 0 :(得分:8)
因为lambda闭包类型和std::function
不是引用相关的。这些是不同的类型。您不能将对std::function
的引用直接绑定到lambda对象。
然而,lambda对象可以转换为std::function
。所以会发生什么是编译器创建一个绑定到该const引用的临时std::function
。在原始问题中创建非常相同的情况。因为每次调用tester
都需要另一个临时对象。临时工作只能活到完全表达的终点,使它们恢复活力。
在第一个代码示例中,main中已经有一个std::function
对象。那个直接绑定到引用,因此您使用相同的引用对象调用tester
。