void MakeMap() {
SetFunctor(&latency1, "latency1");
SetFunctor(&latency2, "latency2");
SetFunctor(&some_variable, "some_key");
...
}
SetFunctor()的实现你会的。
【 在 lorinsz (lorin) 的大作中提到: 】
: 标 题: 这个设计有没有可以改进的地方?
: 发信站: 水木社区 (Sun Sep 12 18:26:55 2021), 站内
:
: 请教各位cpp大牛,这个设计有啥可以改进的地方,让代码看上去简洁优雅一些。
:
: 有一个struct,定义了一堆各种数据类型(int,float,double, array, array<vector>, array<vector<vector>>)的metric,主要是log一个系统的各种performance metric,系统很大很复杂,大概有几百个变量
:
: struct Metrics {
: float latency1; // 几百个这样的变量
: double latency2;
: ...
: };
:
: Metrics类有一个更新其中部分数据的api(每隔几秒会拿到一部分metric的更新值,目前从其他地方传过来是存在一个map里,用的是string->variant): updateMetricsValue(const std::unordered_map<std::string, std::variant>& sample),map一般每次有十几个变量。大部分metric更新是直接赋值,有些需要进行一些简单计算,比如map里存的是一个vector,metric其实要的是平均或者中位数。
:
: 现在我的做法是在Metrics类里搞了一个lambda map用来定义metric的更新函数,对于每一个metric变量写一个lambda,这个map放在了Metrics类里。
: struct Metrics {
: std::unordered_map<std::string, std::function<void(const std::unordered_map<std::string, std::variant> &sample)>> fxMap;
: void makeFxMap() {
: fxMap["latency_1"] = [&latency1](const std::unordered_map<std::string, std::variant> &sample) {
: latency1 = std::get<float>(sample.at("latency_1"));
: };
:
: // 每一个metric的更新方式都要定义一个lambda。
: // ....
: }
: };
:
: 这样写的原因是让updateMetricsValue(sample)比较简洁:
: updateMetricsValue(const std::unordered_map<std::string, std::variant>& sample) {
: for (auto& [key, data] : sample) {
: fxMap[key](sample);
: }
: }
:
: 现在的问题是makeFxMap()这个创建lambda map的函数巨长无比,reflection的模式能用在这里吗?(据我所知C++20还没有)。有没有办法搞个模版函数可以让代码简洁?谢谢!
:
: --
: ※ 修改:·lorinsz 于 Sep 12 18:29:57 2021 修改本文·[FROM: 163.114.132.*]
: ※ 来源:·水木社区
http://www.mysmth.net·[FROM: 163.114.132.*]
--
修改:lorinsz FROM 163.114.132.*
FROM 76.126.252.*