当前位置: 首页 > news >正文

聊聊c++的反射

反射是什么?

就是你可以用一个字符串去修改某个实例的某个字段。

RTTR

这个框架 对低版本的gcc支持还不错,但是最新的0.9.6版本是2018年的。7年多过去了,都没有更新的版本。我的本地gcc版本是14。编译起来一堆问题。实在不推荐高版本环境使用。

boost.pfr

#include <boost/pfr.hpp>
#include <iostream>
#include <string>struct Person {// the order can not changestd::string name;  // public (必须是 public 才能被 PFR 访问)int age;          // the order can not change
};int main() {Person p{"Alice", 30};std::cout << "Fields of Person:\n";boost::pfr::for_each_field(p, [](const auto& field,std::size_t idx) {std::cout << "  [" << idx << "] = " << field << "\n";});std::cout << "Number of fields: " << boost::pfr::tuple_size_v<Person> << "\n";// 按索引访问(name 是第0个,age 是第1个)std::cout << "Name: " << boost::pfr::get<0>(p) << "\n";std::cout << "Age:  " << boost::pfr::get<1>(p) << "\n";// 修改 ageboost::pfr::get<1>(p) = 35;std::cout << "after change Age:  " << boost::pfr::get<1>(p) << "\n";return 0;
}

能正常运行,但是怎么说呢,只能根据编号去修改字段。有点鸡肋。

boost::pfr::get<1>(p) = 35;

而且如上的代码,get里面只能写常量,不能写变量。也就是说想通过filed_name找到编号,然后再把编号传到get里面瑟吉欧不行的。

通过json序列化达到反射的目标


#include <nlohmann/json.hpp>
#include <iostream>
#include <string>struct Person {std::string name;int age{};double salary{};
};NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Person, name, age, salary)bool update_field_via_json(Person& p, const std::string& field, const std::string& value_str) {nlohmann::json j = p;if (!j.contains(field)) {return false;}auto& orig_val = j[field];try {if (orig_val.is_string()) {j[field] = value_str;} else if (orig_val.is_number_integer()) {j[field] = std::stoi(value_str);} else if (orig_val.is_number_float()) {j[field] = std::stod(value_str);} else {return false;} catch (...) {return false;}p = j.get<Person>();return true;
}int main() {Person p{"Alice", 30, 8888.88};std::cout << "Before: " << p.name << ", " << p.age << "\n";if (update_field_via_json(p, "age", "35")) {std::cout << "After: " << p.name << ", " << p.age << "\n"; // age=35}update_field_via_json(p, "name", "Alice Cooper");std::cout << "Name now: " << p.name << "\n";return 0;
}

这种转换 肯定性能不够强,但是一般情况下,如果只是为了修改某个实体的某个字段,也不需要多强的性能

模板方法升级

刚才上面的person可以运行,如果我再加一个Car呢?

#include <nlohmann/json.hpp>
#include <iostream>
#include <string>// 你的结构体
struct Person {std::string name;int age{};double salary{};
};// 自动生成 to_json / from_json
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Person, name, age, salary)// 再定义一个新结构体,无需额外代码!
struct Config {bool debug{};int max_connections{};std::string log_level{};
};
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Config, debug, max_connections, log_level);// ====== 通用更新函数(只需写一次!) ======
template<typename T>
bool update_field_via_json(T& obj, const std::string& field, const std::string& value_str) {nlohmann::json j = obj; // 序列化当前对象if (!j.contains(field)) {return false; // 字段不存在}auto& orig_val = j[field];try {if (orig_val.is_string()) {j[field] = value_str;} else  if (orig_val.is_number_integer()) {j[field] = std::stoll(value_str); // 更安全:支持 long long} else if (orig_val.is_number_float()) {j[field] = std::stod(value_str);} else  if (orig_val.is_boolean()) {// 支持 "true"/"false", "1"/"0"std::string lower = value_str;std::transform(lower.begin(), lower.end(), lower.begin(),[](unsigned char c) { return std::tolower(c); });if (lower == "true" || lower == "1") {j[field] = true;} else if (lower == "false" || lower == "0") {j[field] = false;} else {return false; // 无效布尔值}} else {return false; // 不支持 array/object/null 等复杂类型}} catch (...) {return false; // 转换异常(如 stoi("abc"))}// 反序列化回对象try {obj = j.get<T>();return true;} catch (...) {return false; // 反序列化失败(理论上不应发生)}
}// ============ 测试 ============
int main() {Person p{"Alice", 30, 8888.88};std::cout << "Before: " << p.name << ", " << p.age << "\n";if (update_field_via_json(p, "age", "35")) {std::cout << "After age update: " << p.age << "\n";}update_field_via_json(p, "name", "Alice Cooper");std::cout << "Name now: " << p.name << "\n";Config cfg{false, 100, "info"};update_field_via_json(cfg, "debug", "true");update_field_via_json(cfg, "max_connections", "200");std::cout << "Config: debug=" << cfg.debug<< ", max_conn=" << cfg.max_connections << "\n";return 0;
}
http://www.dtcms.com/a/593892.html

相关文章:

  • 长安做网站公司微信开发时间
  • 做电影网站的软件潍坊网络推广个人合作
  • 零基础学AI大模型之Milvus向量数据库全解析
  • Spring MVC 核心工作原理:DispatcherServlet 全流程深度解析
  • 网站建设计入哪个明细科目在百度如何发布作品
  • 四大AI相关平台特点分析与对比
  • 网站上的链接怎么做wordpress转移服务器
  • 基于微信小程序的个性化漫画阅读推荐系统
  • 压缩上下文以提升大语言模型的推理效率
  • DrawEduMath:评估视觉语言模型的教育领域新基准
  • 医院网站站群建设小程序商店怎么接入视频号
  • 编程课哪个培训机构好肇庆网页关键词优化
  • 外国网站做问卷调查挣钱网站建设对客户的优势
  • 移动通信网络建设-实验3:5G建设方案规划设计
  • 关于文艺网站建设政策展馆展厅设计方案
  • 网站 设计理念上海网站排名
  • 《算法通关指南:算法基础篇 --- 一维前缀和(1)—1. 【模板】前缀和,2.最大子段和》
  • 英文网站设计多少钱wordpress qux
  • 编程语言排行榜2025年11月
  • 现在网站开发的前端语言如何做百度推广
  • 多粒子模型--交通堵塞
  • wordpress快速仿站视频教程wordpress如何进数据库
  • 做的ASP网站手机石家庄seo扣费
  • 扫二维码进入个人的购物网站如何做软件外包公司绩效考核内容
  • iOS的事件响应链
  • iOS Widget 开发-9:可配置 Widget:使用 IntentConfiguration 实现参数选择
  • 教育网站报名网络推广100种方法免费
  • 班级网站设计论文网站制作与网站建设技术
  • 卓拙科技做网站吗网站建设期末论文
  • 【App开发】Android Studio 安装插件(比如通义灵码)