2

ユーザー アプリケーションの構成を保持する構成クラスを作成しており、ファイルから文字列として読み取ります。

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;
};

そのため、アプリを起動すると、構成ファイルを 1 行ずつ読み取り、Config クラスに追加します。

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

アプリで使用するためにこれらの値を別の場所に取得したいのですが、構成クラスのキャストを残す方法はありますか? このようなもの:

//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

しかし、 intfloatbool、またはそれ以外の configKey を複数持つことができます。GetKey(char* keyLabel)で keyTypeを確認し、変換してから返す方法を探しています。

または、より良い解決策に関するアドバイス!

4

3 に答える 3

3

これに使用boost::variantします。

ブーストバリアントを使用すると、各タイプがコピー可能であるという条件で、複数のタイプを表すことができます。

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");
于 2013-07-18T22:42:33.423 に答える
1

テンプレートは使えますか?次のコードは完全に正しいとは限りませんが、少なくともこれがあなたにとって有効な解決策であるかどうかを評価するのに役立つはずです:

//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");
于 2013-07-18T23:05:09.127 に答える
0

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 でないかどうかを確認するとよいでしょう。

于 2013-07-18T22:40:41.920 に答える