嗨,我使用boost::pfr
作为基本反射,它工作正常,但问题是它只打印或处理字段值,就像boost::pfr::io
一样,它打印结构体的每个成员,但我如何将其打印为名称值对,for_each_field
也有同样的问题,函子只接受值,但不接受名称。我如何获得字段名称?
struct S {
int n;
std::string name;
};
S o{1, "foo"};
std::cout << boost::pfr::io(o);
// Outputs: {1, "foo"}, how can I get n = 1, name = "foo"?
字符串
4条答案
按热度按时间7cwmlq891#
如果你认为修改一个结构体不会造成太大的干扰(它不会改变你现有的定义,你甚至不需要把它放在公共头中):
字符串
然后你可以为序列构造一个通用的
operator<<
:型
这里有一个现场演示:Live On Compiler Explorer
型
额外好处:正确引用类字符串类型
Live On Compiler Explorer
型
产出:
型
dy1byipe2#
库不能提供任何这样的功能,因为目前不可能获得类成员的名称作为对象的值。
如果要输出字段名,则需要声明与成员Map的字符串对象,并实现手动使用这些字符串的
operator<<
。要做到这一点,一个更复杂的反射库可能会提供宏来定义成员。宏可以使用提供的名称作为标识符将其参数扩展到声明中,同时也可以使用名称作为字符串字面量(通过
#
宏替换操作符)生成代码。6qfn3psc3#
这是愚蠢的,但嘿,与字符串化宏每个字段可能是足够的你。
字符串
产出:
(n = 2)
(name(嘘)
型
输出
(2,n)
(boo,姓名)
jobtbby34#
这在boost 1.84中是可能的,在最新版本的pfr git repo中也是可能的。你可以使用像
boost::pfr::names_as_array<Type>()
和boost::pfr::get_name<N, Type>
这样的函数(我在使用今天的预发布代码构建后者时遇到了一些问题,但是names_as_array
在所有三大编译器上都解决了)。请参阅文档。(for有关其工作原理的说明,请参阅this answer by Artyer)