我注意到我无法更改存储在std::vector或std::map中的对象的值。下面代码的输出为"0"提供了toggle()函数调用的结果,在这两种情况下。在向量之外直接使用对象时,不存在此行为。我是不是遗漏了一些关于std::vector或类似容器的东西?如何正确地将对象存储在容器中并保持更改其值的能力?
#include <iostream>
#include <functional>
#include <vector>
class OtherThing{
public:
void addElement(std::function<int()> func){
this->myfuncs.push_back(func);
}
void toggle(){
std::cout << "toggle .. " << this->myfuncs[0]() << std::endl;
}
private:
std::vector<std::function<int()>> myfuncs;
};
class Thing: public OtherThing{
public:
Thing(){
std::function<int()> myfunc= [this]()->int{
std::cout << "from lambda " << this->value << std::endl;
return this->value;
};
this->addElement(myfunc);
}
void setValue(int value){
this->value = value;
}
int getValue(){
return this->value;
}
private:
int value;
};
int main() {
// container for things
std::vector<Thing> mythings;
// a thing
Thing a;
mythings.push_back(a);
mythings[0].setValue(666);
mythings[0].toggle();
mythings[0].setValue(999);
mythings[0].toggle();
return 0;
}产出:
clang++-7 -pthread -std=c++17 -o main main.cpp
./main
toggle .. from lambda 0
0
toggle .. from lambda 0
0发布于 2021-10-09 22:01:13
push_back(a)复制了一份a。mythings[0]返回对该副本的引用。因此,任何修改mythings[0]成员的操作都不会反映在a中,反之亦然。
然而,当a被push_back()复制时,Thing的编译器生成的复制构造函数将按原样复制myfuncs向量,因此a的构造函数存储在该向量中的lambda也被复制为- is -,该this指针捕获了指向a的this指针,而不是新的副本。
因此,当您调用mythings[0].setValue()时,您正在修改复制的Thing的value,但是当您调用mythings[0].toggle()时,您调用的是一个打印a的value的lambda --它从一开始就没有初始化过,所以在调用a.setValue()之前输出是不确定的。
要解决这个问题,您需要为Thing实现自己的复制构造函数,该构造函数存储自己的lambda,捕获复制的Thing的this指针,而不是从正在复制的Thing中存储以前的lambda的副本,例如:
Thing(const Thing &src){
value = src.value;
std::function<int()> myfunc = [this]()->int{
std::cout << "from copied lambda " << this->value << std::endl;
return this->value;
};
this->addElement(myfunc);
}发布于 2021-10-10 12:33:17
我也是根据这些评论来尝试的。老实说,我不喜欢这样。脚本太多,不能调用toggle()
#include <iostream>
#include <functional>
#include <vector>
class Thing;
class OtherThing{
public:
void addElement(std::function<int(Thing*)> func){
this->myfuncs.push_back(func);
}
void toggle(Thing* obj){
std::cout << "toggle .. " << this->myfuncs[0](obj) << std::endl;
}
private:
std::vector<std::function<int(Thing*)>> myfuncs;
};
class Thing: public OtherThing{
public:
Thing(){
std::function<int(Thing*)> myfunc= [](Thing* obj)->int{
std::cout << "from lambda " << obj->value << std::endl;
return obj->value;
};
this->addElement(myfunc);
}
void setValue(int value){
this->value = value;
}
int getValue(){
return this->value;
}
private:
int value;
};
int main() {
// container for things
std::vector<Thing> mythings;
// a thing
Thing a;
// copy is here
mythings.push_back(a);
// test
mythings[0].setValue(666);
mythings[0].toggle(&mythings[0]);
mythings[0].setValue(999);
mythings[0].toggle(&mythings[0]);
return 0;
}产出:
toggle .. from lambda 666
666
toggle .. from lambda 999
999https://stackoverflow.com/questions/69510628
复制相似问题