将字符串评估为类变量
Posted
技术标签:
【中文标题】将字符串评估为类变量【英文标题】:Evaluate string to class variable 【发布时间】:2013-05-31 18:32:45 【问题描述】:我需要评估一个字符串,以便为类变量赋值:
类:
class DATACLASS
public:
double variable1, variable2, variable3;
;
void init():
void init()
DATACLASS *d = new DATACLASS;
std::string ssList[3] = "variable1",
"variable2",
"variable3";
for(unsigned i = 0; i < 3; ++i)
std::stringstream ss;
ss << ssList[i];
//ss.str().c_str() correspond to "variable1", "variable2", "variable3"
mxArray *array_ptr = mexGetVariable("base", ss.str().c_str());
double pr = (double)mxGetPr(array_ptr)[0];
// How to make the same thing here?
// I would like to have something that would evaluate
// data->ssList[i] = pr;
// or more precisely
// data->variable1 = pr;
// but from the ss string like below (but this doesn't work)
data->ss.str().c_str() = pr;
我在尝试这样做时遇到这种错误:
error C2039: 'ss' : is not a member of 'DATACLASS'
【问题讨论】:
这叫做 reflection,如果你想用谷歌搜索它。简短的回答:你不能在 C++ 中做到这一点。使用其他语言,或查看您的设计。 在 C++ 中没有像 javascript 那样对此的内置支持。有些人尝试构建您可能可以使用的反射框架,但我从未测试过。如果您真的想要这种东西,您将不得不自己伪造它。 @AlexandreC。很高兴知道我正在尝试做的事情有一个术语。我真的不知道要找什么。看来我得重新审视我的设计了。 【参考方案1】:这不是有效的 C++。编译器认为您正在尝试做的是访问名为 ss
的 DATACLASS
实例的成员并在其上调用一些方法。
您尝试做的事情可以在反射中完成,这在 C++ 中不受支持。您可以通过使用模板使用某种形式的伪反射模型来半途而废。
【讨论】:
如果您知道所有字段都将是同一类型,然后使用ss.str()
对其进行索引,则可以像拥有一个映射(键值对列表)一样简单。我建议你不要尝试使用模板魔法或其他伪反射,除非你对自己的 C++ 能力相当有信心。【参考方案2】:
你只读双打吗?为此,您可以使用指向数据成员的指针。
std::map<std::string, double DATACLASS::*> aMembers;
aMembers["variable1"] = &DATACLASS::variable1;
aMembers["variable2"] = &DATACLASS::variable2;
aMembers["variable3"] = &DATACLASS::variable3;
DATACLASS dc;
std::string sData = "variable1";
dc.*aMembers[sData] = 10;
在完整的解决方案中,您当然必须首先检查 aMembers[sData] 是否存在。如果您需要支持多种数据类型,则需要使用模板并编写一些支持类。不过应该是可行的。
【讨论】:
【参考方案3】:您可以在不费力气的情况下合理地到达最接近的位置,如下所示。您可以使用宏、函数、容器、模板、指针/引用等抽象出一些东西,但这是基本要点。除非您有令人信服的理由,否则我不建议您这样做并花时间去做。你的最终目标是什么?
class DATACLASS
public:
double variable1, variable2, variable3;
;
void init()
DATACLASS *d = new DATACLASS;
std::string ssList[3] = "variable1",
"variable2",
"variable3";
for(unsigned i = 0; i < 3; ++i)
std::stringstream ss;
ss << ssList[i];
//ss.str().c_str() correspond to "variable1", "variable2", "variable3"
mxArray *array_ptr = mexGetVariable("base", ss.str().c_str());
double pr = (double)mxGetPr(array_ptr)[0];
if(ss.str() == "variable1")
data->variable1 = pr;
else if(ss.str() == "variable2")
data->variable2 = pr;
else if(ss.str() == "variable3")
data->variable3 = pr;
【讨论】:
这是在添加 for 循环之前的编码方式。因为可能存在大量变量,所以我尽量避免使用 if else if。 @m_power 我明白了。那让我看看能不能给你想点别的办法。如果这些值总是编译时常量会更容易,但这将是一个不那么有趣的问题:) @m_power 由于运行时问题(速度、代码大小)或开发问题(重复输入的数量、错误风险、可维护性噩梦),您是否试图避免if
语句?
用于简化代码和可移植性。但一开始,我并不知道在 cpp 中反射是不可能的。所以如果没有其他选择,我可能会结束使用if
语句。以上是关于将字符串评估为类变量的主要内容,如果未能解决你的问题,请参考以下文章