[英]How can I capture the element in a vector in C++ Lambda?
我用 Lambda 初始化了一個實例,其中 Lambda 可以通過引用捕獲實例來修改實例 state。 當我將實例放入向量中並調用 Lambda 時,Lambda 會修改原始初始化實例而不是向量中的實例。
#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
*/
}
非常感謝大家。 這有助於我了解這里發生了什么以及如何解決它。
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;
}
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,我沒有嘗試再次修改原始實例,如果您仍然有興趣互相引用方法,請自行嘗試。
當我將實例放入向量中時
你不能那樣做。 您可以將實例復制到矢量元素中。 在 C++ 和 object是它占據的 memory。
我可以通過捕獲原始引用的 Lambda 來修改容器實例 state,反之亦然?
因為它們是獨立的對象,所以它們需要某種相互引用的方式,例如BoolState * other
成員。
將元素放置到容器中確實會在適當位置構造元素。 使用您提供的參數調用構造函數。 當您只需將其復制/移動到容器中時,它有助於避免創建不必要的實例。
但是,如果您確實已經有一個實例,那么放置一個元素與推送它並沒有太大區別:該參數用於調用復制構造函數,您最終會在容器中獲得一個副本。
術語可能有點誤導,因為您永遠不能先創建 object,然后將 object 放入容器中。 考慮一個 c 數組的簡單情況:
int x;
int a[3];
沒有辦法擁有&x == &a[0]
,即容器內的元素可以相等,但與外面的元素不同。 當然,您可以使用一定程度的間接(例如指針)來模擬它。
這是真正的最小示例:
#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
向量擁有它們的內容。 他們通過復制你給他們的東西來做到這一點。
您在main
中的 object 與向量中的 object 不同。 修改一個不會修改另一個。
這並不意味着你不能做你想做的事,但你必須給向量中的 object 一個名字才能捕獲它:
BoolState& bsInVector = bss.at(0);
auto func = [&bsInVector]() { /* ... */ };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.