将字符串评估为类变量

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++。编译器认为您正在尝试做的是访问名为 ssDATACLASS 实例的成员并在其上调用一些方法。

您尝试做的事情可以在反射中完成,这在 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 语句。

以上是关于将字符串评估为类变量的主要内容,如果未能解决你的问题,请参考以下文章

将 PHP 数组转换为类变量

将声明的枚举转发为类成员变量

我可以将实体框架上下文保留为类变量吗?

如何将静态 const 变量保留为类的成员

如何将值设置为类的变量并显示它?

Static int data语句说明data为类变量,为一个类的共享变量,属于整个类