【问题标题】: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。很高兴知道我正在尝试做的事情有一个术语。我真的不知道要找什么。看来我得重新审视我的设计了。

标签: c++ string class


【解决方案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 语句。
    猜你喜欢
    • 2022-01-19
    • 2014-08-31
    • 1970-01-01
    • 2019-07-09
    • 1970-01-01
    • 2013-06-01
    • 2020-02-29
    • 2010-09-28
    相关资源
    最近更新 更多