为什么C++中std::reference_wrapper的该用法无法修改原Entity实例?
问题分析
你的代码存在两处核心问题导致原实例属性未被修改:
- 第一处是
simThread函数内的实例拷贝逻辑
你用Entity e = simulation_entities[i];取值时,尽管simulation_entities里存储的是std::reference_wrapper<Entity>引用包装器,但直接赋值给Entity类型变量会触发拷贝构造,后续调用e.tick()修改的都是栈上临时拷贝对象的属性,完全不会作用到原实例上。 - 第二处可能存在声明实现不一致的问题
你提到最初addEntity的签名是传值addEntity(Entity e),如果头文件中的声明没有同步修改为引用版本addEntity(Entity& entity),那调用该函数时传入的本身就是原实例的临时拷贝,你存储的引用会在函数执行结束后变为悬垂引用,后续操作属于未定义行为,自然无法修改原实例。
修复方案
- 首先确认头文件中
addEntity的声明和实现完全一致,参数为Entity&类型,保证传入的是main中实例的引用。 - 修改
simThread中的取值代码,直接获取引用避免拷贝:
// 两种写法二选一即可,第二种更明确避免隐式转换问题 Entity& e = simulation_entities[i]; // 或者 auto& e = simulation_entities[i].get();
- 额外优化建议:
tick方法的参数目前是传值vector<std::reference_wrapper<Entity>> e,每次调用都会拷贝整个vector,性能开销很高,建议修改为传常量引用:
void Entity::tick(const vector<std::reference_wrapper<Entity>>& e)
内容的提问来源于stack exchange,提问作者Jan Ráček
相关产品推荐
相关产品推荐

