欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 2407C++,编译期反射库

2407C++,编译期反射库

2024/10/25 2:30:57 来源:https://blog.csdn.net/fqbqrr/article/details/140397137  浏览:    关键词:2407C++,编译期反射库

原文

以前的编译期反射,大多需要写一个助手宏或额外的代码去实现,比如iguana就是如此,iguana中需要这样定义一个结构才能实现编译期反射:

struct simple {int color;int id;std::string str;int age;
};
REFLECTION(simple, color, id, str, age);

虽然这是非侵入式的,但是字段多了,写该宏也是很麻烦的,能不能去掉该宏?
现在可愉快的声明:在C++20中终于可去掉该宏了!

yalantinglibs.reflection库已实现了无需宏和非侵入式编译期反射函数,让来看看雅兰亭库编译期反射库的用法吧.

struct simple {int color;int id;std::string str;int age;
};using namespace ylt::reflection;int main() {simple p{.color = 2, .id = 10, .str = "hello reflection", .age = 6};//编译期取结构所字段个数static_assert(members_count_v<simple> == 4);//编译期取结构所有字段名的数组constexpr auto arr = get_member_names<simple>();//根据编译期索引取值CHECK(std::get<3> == 6); //`取年龄`CHECK(std::get<2> == "hello reflection"); //取串//根据运行期索引取值size_t index = 3;auto var = get(p, index);CHECK(*std::get<3>(var) == 6);//或`visit`访问std::visit([](auto field_value_ptr) {std::cout << *field_value_ptr << "\n";},var);//遍历结构取得字段值和字段名for_each(p, [](auto& field_value, auto field_name) {std::cout << field_value << ", " << field_name << "\n";});//遍历结构取得字段值,字段名和索引for_each(p, [](auto& field_value, auto field_name, size_t index) {std::cout << field_value << ", " << field_name << "\n";});
}

现在对简单结构,不需要写额外的代码就可实现编译期反射了,比如编译期取字段个数,字段名,根据索引取字段值,遍历结构,取字段值,字段名和索引.
酷不酷?
你以为就这些了吗,不,还有一些很酷的没展示:比如根据字段名字取字段值,根据字段名字取字段索引,根据字段索引取字段名字.

  //编译期根据字段名取字段值auto& age2 = get<"age"_ylts>(p);CHECK(age2 == 6);auto& var1 = get<"str"_ylts>(p);CHECK(var1 == "hello reflection");//运行期根据字段名取字段值std::string field_name = "str";auto var2 = get(p, field_name);CHECK(*std::get<2>(var2) == "hello reflection");std::visit([](auto ptr) {std::cout << *ptr << "\n";},var2);//根据编译期索引取字段名constexpr std::string_view name1 = name_of<simple, 2>();CHECK(name1 == "str");//根据运行期索引取字段名size_t index = 2;constexpr std::string_view name2 = name_of<simple>(index);CHECK(name2 == "str");//根据编译期字段名取字段索引constexpr size_t idx = index_of<simple, "str"_ylts>();CHECK(idx == 2);constexpr size_t idx1 = index_of<simple>("str");CHECK(idx1 == 2);// 根据运行期字段名取字段索引std::string field_name = "str";size_t idx2 = index_of<simple>("str");CHECK(idx2 == 2);

除此外,还支持根据运行期字段的值来取字段名和字段索引:

  int& age1 = p.age;size_t idx4 = index_of(p, age1);CHECK(idx4 == 3);auto name3 = name_of(p, age1);CHECK(name3 == "age");

更多测试代码:这里
现在感觉如何?是不是正是你需要的编译期反射库呢?
后面json,xml,yaml,protobuf都会基于yalantinglibs该反射库重构,让用户摆脱宏,代码也会写得更舒服.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com