【发布时间】:2020-07-22 08:11:35
【问题描述】:
场景:
我用其中的 Lambda 初始化了一个实例,Lambda 可以通过引用捕获实例来修改实例状态。 当我将实例放入向量中并调用 Lambda 时,Lambda 会修改原始初始化实例,而不是向量中的实例。
最小的 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
*/
}
问题:
- 由于我在 Lambda 中通过引用捕获了实例,如何 原始初始化实例和向量中的实例为 2 不同的实例? (我可以打印出 2 个实例在内存中有 2 个不同的地址,但我不明白:为什么会这样?这会如何影响结果?)
- 能否通过 Lambda 捕获原始引用来修改容器实例状态,反之亦然?
根据@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,我没有再尝试修改原始实例,如果您仍然有兴趣互相引用方法,请自行尝试。
【问题讨论】:
-
请不要在您的答案中添加解决方案。从某种意义上说,这是在破坏您的问题。但是,如果您想添加答案,可以这样做