Не могу поверить, что я собираюсь предложить это, но здесь ...
Определите простой attribute
класс, который является оберткой вокруг std::string
- который является вашей ценностью.Этот класс должен предоставлять операторы преобразования (насколько мне они не нравятся, в этом случае они могут немного облегчить жизнь).
#include <iostream>
#include <boost/lexical_cast.hpp>
struct attribute
{
std::string value;
operator bool() const { return boost::lexical_cast<bool>(value); }
operator int() const { return boost::lexical_cast<int>(value); }
operator unsigned int() const { return boost::lexical_cast<unsigned int>(value); }
operator double() const { return boost::lexical_cast<double>(value); }
operator std::string() const { return value; }
};
int main(void)
{
attribute a = { "foo" };
attribute b = { "10" };
std::string sa = a;
int sb = b;
unsigned int su = b;
std::cout << sa << std::endl;
std::cout << sb << std::endl;
std::cout << su << std::endl;
}
Итак, здесь тип переменной, которой вы назначаете, определяетпреобразование, которое применяется.Теперь главная проблема при таком подходе заключается в том, что если нет оператора прямого преобразования, компилятор выберет наилучшее совпадение - что может не всегда быть тем, что вы хотите.Поэтому, чтобы быть в безопасности, определите все необходимые вам преобразования, и вы можете быть в порядке.
Затем сохраните этот attribute
вместе с вашим строковым ключом на карте (ПРИМЕЧАНИЕ: вам нужно будет использовать ctor по умолчанию)скопируйте ctor / assign op и т. д., поскольку настройки по умолчанию небезопасны).Если вы не можете быть обеспокоены последним, сохраните умный указатель на карте, например,
std::map<std::string, boost::shared_ptr<attribute> > attributes;
Теперь ваш интерфейс должен принять ключ и вернуть attribute
, например,
attribute const& get(std::string const& some_key)
{
map<>::iterator it = attributes.find(some_key);
return *it->second;
}
bool bv = get(some_key); // automatically converted to bool (if lexical_cast doesn't throw)