场景:
我用Lambda初始化了一个实例,其中Lambda可以通过按引用捕获实例来修改实例状态。
当我将实例放入 vector 中并调用Lambda时,Lambda会修改原始初始化的实例,而不是 vector 中的实例。
最小的C++程序来说明:
#include <iostream>
#include <functional>
#include <vector>
struct BoolState {
bool _stateChangeByInstanceReference = false;
bool _stateChangeByContainerReference = false;
std::function<void()> _changeStateByInstanceReference;
std::function<void()> _changeStateByContainerReference;
};
int main()
{
using namespace std;
vector<BoolState> bss;
BoolState bs;
bs._changeStateByInstanceReference = [&bs]() -> void { bs._stateChangeByInstanceReference = true; };
bs._changeStateByContainerReference = [&bss]() -> void { bss.at(0)._stateChangeByContainerReference = true; };
bss.emplace_back(bs);
bss.back()._changeStateByInstanceReference();
bss.back()._changeStateByContainerReference();
cout << "The original instance by instance reference: " << bs._stateChangeByInstanceReference << endl;
cout << "The original instance by container reference? " << bs._stateChangeByContainerReference << endl;
cout << "The container instance by instance reference? " << bss.back()._stateChangeByInstanceReference << endl;
cout << "The container instance by container reference: " << bss.back()._stateChangeByContainerReference << endl;
/*
The original instance by instance reference: 1
The original instance by container reference? 0
The container instance by instance reference? 0
The container instance by container reference: 1
*/
}
题:原始初始化实例和vector中的实例均为2
不同的实例? (我可以打印出这2个实例在内存中有2个不同的地址,但我不明白:为什么是这种情况?这将如何影响结果?)
根据@Asteroids With Wings,@ idclev 463035818和@Caleth的解决方案:
非常感谢大家!这对我很有帮助,可以了解这里发生的情况以及如何解决它。
根据@Asteroids With Wings的push_back()版本:
int main()
{
using namespace std;
vector<BoolState> bss;
BoolState bs;
bs._changeStateByContainerReference = [&bss]() -> void { bss.at(0)._stateChangeByContainerReference = true; };
// Only copy container version Lambda
bss.push_back(bs);
// Modify in place with instance version Lambda
BoolState& bsInbss = bss.at(0);
bss.at(0)._changeStateByInstanceReference = [&bsInbss]() -> void { bsInbss._stateChangeByInstanceReference = true; };
bss.at(0)._changeStateByInstanceReference();
bss.at(0)._changeStateByContainerReference();
cout << "The container instance by instance reference:(solved) " << bss.back()._stateChangeByInstanceReference << endl;
cout << "The container instance by container reference: " << bss.back()._stateChangeByContainerReference << endl;
}
@idclev 463035818的“真实” emplace_back()版本int main() {
using namespace std;
vector<BoolState> bss;
bss.emplace_back(BoolState());
BoolState& bsInbss = bss.at(0);
bss.at(0)._changeStateByInstanceReference = [&bsInbss]() -> void { bsInbss._stateChangeByInstanceReference = true; };
bss.at(0)._changeStateByContainerReference = [&bss]() -> void { bss.at(0)._stateChangeByContainerReference = true; };
bss.at(0)._changeStateByInstanceReference();
bss.at(0)._changeStateByContainerReference();
cout << "The container instance by instance reference:(solved) " << bss.back()._stateChangeByInstanceReference << endl;
cout << "The container instance by container reference: " << bss.back()._stateChangeByContainerReference << endl;
}
感谢@Caleth,我没有尝试再次修改原始实例,如果您仍然对互相引用的方法感兴趣,请尝试一下。
最佳答案
这是真正的最小示例😉:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
int x = 42;
v.emplace_back(x);
std::cout << &x << '\n';
std::cout << &v[0] << '\n';
}
// 0x7ffd008d9d14
// 0x1f7fc20
(live demo)vector 拥有其内容。他们通过复制您给他们的东西来做到这一点。
main
中的对象与 vector 中的对象不同。修改一个不会修改另一个。这并不意味着您不能做您想做的事,但是您必须给 vector 中的对象起一个名字才能捕获它:
BoolState& bsInVector = bss.at(0);
auto func = [&bsInVector]() { /* ... */ };
关于c++ - 如何在C++ Lambda中捕获 vector 中的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63029711/