typeid() Object-Oriented Design Alternative
c++, collections, oop, typeid
Solution
This is a perfect fit for template specialization:
template<>
void MyMaps::addKey<string>(const string& key)
{
stringFields.insert(pair<string, string>(key, string()));
}
template<>
void MyMaps::addKey<int>(const int& key)
{
intFields.insert(pair<string, int>(key, int()));;
}
template<>
void MyMaps::addKey<float>(const float& key)
{
floatFields.insert(pair<string, float>(key, float()));
}
EDIT: For syntax/more info about template specialization read: Template Specialization and Partial Template Specialization
Or better yet, if boost is an option and if the keys are unique for all 3 maps and you have 3 different maps just to be able to store them, then consider using `boost::variant`:
typedef boost::variant<string, int, float> ValueType;
class MyMap
{
public:
typedef std::map<std::string, ValueType> MapType;
template<typename T> void addKey(const std::string& key, T &val)
{
ValueType varVal= val;
allFields.insert(MapType::value_type(key, varVal));
}
private:
MapType allFields;
};
Problem
I have the following class using 3 different maps: keys are always strings, while values may be strings, integers or floats. ``` class MyMaps { public: template<typename T> void addKey(const std::string& key); void addValue(const std::string& key, const std::string& value); void addValue(const std::string& key, int value); void addValue(const std::string& key, float value); private: std::map<std::string, std::string> stringFields; std::map<std::string, int> intFields; std::map<std::string, float> floatFields; }; ``` The `addValue()` functions simply add a new pair to the related map. What I'm working on is the `addKey()` template function: ``` /** Add only a key, the related value is a default one and is specified by template parameter T. */ template<typename T> void MyMaps::addKey(const string& key) { if (typeid(T) == typeid(string)) { stringFields.insert(pair<string, string>(key, string())); } else if (typeid(T) == typeid(int)) { intFields.insert(pair<string, int>(key, int()));; } else if (typeid(T) == typeid(float)) { floatFields.insert(pair<string, float>(key, float())); } } ``` Basically, I'm using `template` and `typeid()` because I don't like this alternative that relies on type-within-function-name: ``` void MyMaps::addStringKey(const string& key) { stringFields.insert(pair<string, string>(key, string())); } void MyMaps::addIntKey(const string& key) { intFields.insert(pair<string, int>(key, int())); } void MyMaps::addFloatKey(const string& key) { floatFields.insert(pair<string, float>(key, float())); } ``` The first `addKey()` version seems working, but I'm wondering if there is a more elegant solution. Maybe I'm missing some Object-Oriented design concept that could be helpful in this case? Thanks in advance.