我最近打开了 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
函数的定义位置和方式。
最佳答案
因为 lambda 闭包类型和 std::function
不是引用相关的。这些是不同的类型。您不能将对 std::function
的引用直接绑定(bind)到 lambda 对象。
但是,lambda 对象可以转换为 std::function
。因此,编译器会创建一个绑定(bind)到该常量引用的临时 std::function
。在您的原始问题中创造非常相同的情况。因为每次调用 tester
都需要另一个临时对象。临时对象只会活到使它们焕然一新的完整表达的尽头。
在第一个代码示例中,main 中已经有一个 std::function
对象。该对象直接绑定(bind)到引用,因此您使用相同的引用对象调用 tester
。
关于c++ - 同一个lambda的不同定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48248176/