我试图将Python程序翻译成C++,但是因为我是C++新手,所以遇到了一些问题:首先解析输入文件(可以工作,未显示)以创建INITIAL_VALUES
dict/map,然后我想使用DEST_DICT_PARAMS
dict/map来分配Parameters
class/struct属性。
我可以用Python代码实现这一点:
import dataclasses
INITIAL_VALUES = {
"BULK": {
"MAGMA": {
"M0": 1.0,
"T0": 1320.0,
},
"ASSIM": {
"M0": 0.0,
"T0": 600.0,
},
}
}
DEST_DICT_PARAMS = {
'M0': {"MAGMA": 'Mm0', "ASSIM": 'Ma0'},
'T0': {"MAGMA": 'Tm0', "ASSIM": 'Ta0'},
}
@dataclasses.dataclass
class Parameters:
Mm0: float = None
Ma0: float = None
Ta0: float = None
Tm0: float = None
class ParametersReader:
def __init__(self):
self.parameters = Parameters()
self._assignParameters()
def _assignParameters(self):
for param_fam, dest in DEST_DICT_PARAMS.items():
for component, param in dest.items():
value = INITIAL_VALUES["BULK"][component][param_fam]
setattr(self.parameters, param, value)
params = ParametersReader()
print(params.parameters)
输出:
参数(平均温度= 1.0,平均湿度= 0.0,平均温差= 600.0,平均温差= 1320.0)
所以我写了相应的C++代码:
#include <iostream>
#include <map>
using std::map;
using std::string;
map<string, map<string, map<string, float> > > INITIAL_VALUES = {{
"BULK", {
{"MAGMA", {
{"M0", 1.0},
{"T0", 1320.0},
}},
{"ASSIM", {
{"M0", 0.0},
{"T0", 600.0},
}},
}
}};
map<string, map<string, string> > DEST_DICT_PARAMS = {{
{"M0", {{"MAGMA", "Mm0"}, {"ASSIM", "Ma0"}}},
{"T0", {{"MAGMA", "Tm0"}, {"ASSIM", "Ta0"}}},
}};
struct Parameters {
float Mm0;
float Ma0;
float Ta0;
float Tm0;
} parameters;
class ParametersReader {
public:
void assignParameters_() {
map<string, map<string, string> >::iterator itr0;
map<string, string>::iterator itr1;
for (itr0 = DEST_DICT_PARAMS.begin(); itr0 != DEST_DICT_PARAMS.end(); itr0++) {
for (itr1 = itr0->second.begin(); itr1 != itr0->second.end(); itr1++) {
parameters.itr1->second = INITIAL_VALUES["BULK"][itr1->first];
}
}
}
};
int main() {
ParametersReader params;
params.assignParameters_();
}
但是我在parameters.itr1->second = INITIAL_VALUES['BULK'][itr1->first]
行遇到一个错误,说"'Parameters'中没有名为'itr1'的成员"。这个错误完全有意义,因为代码试图将'itr1'解释为属性名称,而不是将整个'itr1-〉second'解释为名称。我认为这归结为一个事实,即我似乎找不到Python的C等价物。s setattr(obj, name, val)
函数,该函数接受一个对象及其属性名并为其赋值。对于我正在尝试的操作,有C解决方案吗?
也许我的整个方法都与C不兼容。如果是这样,你能建议一种替代方法吗?我希望Python和C版本的输入文件格式保持一致。
2条答案
按热度按时间ryevplcw1#
C++不像Python那样有运行时反射。你不能使用运行时字符串按名称查找类成员,因为类成员名称在运行时不存在。
你 * 能 * 做的就是通过一个 * 指向member* 的指针 * 来查找类成员,这是编译器在编译时计算的对象偏移量:
Demo
注我还使用了基于范围的for循环和结构化绑定来清理
assignParameters_
函数。1hdlvixo2#
C++没有Python
setattr(self.parameters, param, value)
的等价物。如果你想在字符串和成员之间有一个Map,你需要自己编写它。您可以使用指向成员的指针执行以下操作:
请注意,代码假定
values
中存在的所有字符串也存在于mmap
中。如果不存在,它将严重失败。要修复此问题,应改用mmap.find
,并适当处理未找到字符串的情况。这是可行的,尽管没有办法只从类定义中隐式地得到Map,但另一方面,我可以想象库的存在可以帮助实现这一点。