简体   繁体   中英

C++ returning an unknown type

I'm making a Configuration class that will hold my user application's configuration, and it reads from a file as strings.

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

So when I start the app, I read the config file line by line and add to my Config class:

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

Now I want to retrieve these values somewhere else for use in the app, is there a way I can leave the cast for the Configuration class? Something like this:

//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");

The reason is so I don't have a bunch of stringstreams elsewhere in the code converting the config values before I can use them. I would save the configKey's type as well in the ConfigKey so it can auto-convert itself.

Any advice or suggestions?

Edit for clarification:

I want to retrieve a configKey using this method:

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

So elsewhere in the code I can call:

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

But I can have multiple configKeys that are either int , float , bool or even something else. I'm looking for a way to have the GetKey(char* keyLabel) to check for the keyType, then convert it, then return it.

Or any advice on a better solution!

Use boost::variant for this.

Boost variant allows you to represent multiple types with the condition that each type is copyable.

boost::get will allow you to get a type out of the variant.

Usage example:

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

std::vector<string_or_int> data;

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

You can make a template using this concept to get whatever configuration information you want:

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

Usage:

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");

Can you use templates? The following code may not be totally correct, but should at least help you evaluate whether this is a solution that will work for you:

//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");

You can override the conversion operator for ConfigKey class and return an instance of it.

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

You might have to perform the conversion explicitly in case the compiler complains:

//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");

In case of an error in the conversion (eg the string does not represent a number) you can throw an exception. Also, would be nice to check if "windowHeight" does not have the value of 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM