如何在不获取包装值的情况下将类实例插入RTTR sequential view?
问题分析
你的核心问题出在RTTR variant的包装特性和set_value的目标对象错误上:
CreateInst函数中,你已经获取了解包后的实际Item实例localobj,但调用p.set_value时却传入了原始的包装inst,导致赋值根本没作用在真正的Item对象上。- 直接将包装了Item的variant传给
view.set_value,RTTR会把包装对象本身当作值插入容器,而非里面的Item实例,所以容器里的Item是默认构造的(i=0),而非你修改后的实例。
解决方案
下面是修正后的代码,无需提取包装值即可正常工作:
#include <iostream> #include <rttr/type> #include <rttr/registration.h> using namespace rttr; struct Item { int i ; }; struct MyTestClass { std::vector<Item> seq; }; RTTR_REGISTRATION { using namespace rttr; registration::class_<MyTestClass>("TestClass") .constructor<>() .property("seq", &MyTestClass::seq); registration::class_<Item>("Item") .constructor<>() .property("item", &Item::i); } void CreateInst(rttr::instance inst) { auto localobj = inst.get_type().get_raw_type().is_wrapper() ? inst.get_wrapped_instance() : inst; auto p = localobj.get_type().get_property("item"); // 修正:赋值给解包后的实际实例localobj,而非原始包装inst p.set_value(localobj, 100); } int main() { MyTestClass inst; for (auto prop : rttr::type::get_by_name("TestClass").get_properties()) { auto type = prop.get_type(); if (type.is_sequential_container()) { auto val = prop.get_value(inst); auto view = val.create_sequential_view(); view.set_size(1); //just for demo rttr::variant var = view.get_value_type().create(); CreateInst(var); // 关键:传入解包后的实例,而非包装的variant view.set_value(0, var.get_wrapped_instance()); prop.set_value(inst, val); } } std::cout << inst.seq[0].i << std::endl; // 现在输出100 }
关键修改点说明
- 修正CreateInst的赋值目标:原来的
p.set_value(inst, 100)是给包装variant赋值,实际应该操作解包后的localobj,这样修改才会作用在真正的Item对象上。 - 传递解包后的实例给view.set_value:
var.get_wrapped_instance()获取到variant内部包装的Item实例,直接将这个实例传给set_value,RTTR会正确将其插入容器,而不是插入包装对象。
这种方式完全通过RTTR的instance接口完成操作,无需显式提取包装值,符合通用序列化的需求。
内容的提问来源于stack exchange,提问作者ray_linn
相关产品推荐
相关产品推荐

