【问题标题】:C++ returning an unknown typeC++ 返回未知类型
【发布时间】:2013-07-18 22:31:57
【问题描述】:

我正在创建一个配置类来保存我的用户应用程序的配置,它从文件中读取字符串。

class ConfigKey
{
    public:
        string KeyLabel; //Will be used to identify this key
        string KeyValue; //The value
        bool IsEditable; //For developing uses only, I'm saving a few default and non editable keys for specific apps here
};
class Configuration
{
    public:
        void AddKey(char* keyLabel, char* keyValue, bool isEditable);
    private:
        vector<ConfigKey> configKeys;
};

所以当我启动应用程序时,我会逐行读取配置文件并添加到我的 Config 类中:

//Constructor
Configuration::Configuration()
{
    //read from file, examples
    AddKey("windowWidth", "1024", false);
    AddKey("windowHeight", "768", false);
}

现在我想在其他地方检索这些值以在应用程序中使用,有没有办法可以让 Configuration 类的演员表? 像这样的:

//In the Configuration class
void* GetKey(char* keyLabel);

//And when I call it, I'd like to do something like this:
int windowAspectRatio = myApp.config.GetKey("windowWidth") / myApp.config.GetKey("windowHeight");

原因是在我可以使用它们之前,我在代码的其他地方没有一堆字符串流来转换配置值。 我会将 configKey 的类型也保存在 ConfigKey 中,以便它可以自动转换。

有什么意见或建议吗?

编辑澄清:

我想用这个方法获取一个 configKey:

//In the Configuration Class
public:
    int GetKey(char* keyLabel)
    { 
        //the value I saved in ConfigKey is a "string" type, but I'm converting it to Int before I return it
        //loop through the vector, find the keyLabel
        stringstream mySS(foundKey.KeyValue);
        int returnValue = 0;
        mySS >> returnValue; //converted the string to int

        return returnValue; //returned an int
    }

所以我可以在代码的其他地方调用:

int myWidth = myConfig.GetKey("windowWidth"); //It's already converted

但我可以有多个 configKeys,它们可以是 intfloatbool 甚至是其他东西。 我正在寻找一种方法让 GetKey(char* keyLabel) 检查 keyType,然后转换它,然后返回它。

或任何关于更好解决方案的建议!

【问题讨论】:

  • 请澄清。 “有没有办法让我为配置类留下演员表”是什么意思。我不确定你在这里问什么。
  • 就我个人而言,我会有int GetIntKey(...)string GetStringKey(...) 等等。

标签: c++ string type-conversion stringstream


【解决方案1】:

为此使用boost::variant

Boost 变体允许您表示多种类型,条件是每种类型都是可复制的。

boost::get 将允许您从变体中获取类型。

使用示例:

using string_or_int = boost::variant<std::string, int>;

std::vector<string_or_int> data;

std::string& s = boost::get<std::string>(data[0]);

您可以使用此概念制作模板来获取您想要的任何配置信息:

template<typename T> T get_config_data(const std::string& key) {
    return boost::get<T>( some_variant );
}

用法:

std::string window_name = config.get_config_data<std::string>("WindowName");
int window_width = config.get_config_data<int>("WindowWidth");
int window_height = config.get_config_data<int>("WindowHeight");

【讨论】:

  • 我不认为我可以为此使用 boost,但是使用示例让我知道了如何解决它,谢谢!
【解决方案2】:

你可以使用模板吗?以下代码可能并不完全正确,但至少应该可以帮助您评估这是否是适合您的解决方案:

//In the Configuration Class
public:
    template< typename T >
    T GetKey(char* keyLabel)
    { 
        stringstream mySS( foundKey.KeyValue );
        T returnValue;
        mySS >> returnValue;
        return returnValue;
    }

// elsewhere
int myWidth = myConfig.GetKey< int >("windowWidth");

【讨论】:

    【解决方案3】:

    您可以覆盖 ConfigKey 类的转换运算符并返回它的一个实例。

    class ConfigKey
    {
        public:
            string KeyLabel; //Will be used to identify this key
            string KeyValue; //The value
            bool IsEditable; //For developing uses only, I'm saving a few default and non editable keys for specific apps here
            operator int();  //Returns an integer representation of KeyValue
    };
    

    如果编译器抱怨,您可能必须显式执行转换:

    //In the Configuration class
    void* GetKey(char* keyLabel);
    
    //And when I call it, I'd like to do something like this:
    int windowAspectRatio = (int)myApp.config.GetKey("windowWidth") / (int)myApp.config.GetKey("windowHeight");
    

    如果转换出错(例如字符串不代表数字),您可以抛出异常。另外,最好检查一下“windowHeight”的值是否不为 0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多