Как я могу хранить различные типы значений в массиве с помощью C ++? - PullRequest
1 голос
/ 30 мая 2011

У меня проблемы с некоторыми функциями, которые я хочу реализовать в своем классе конфигурации, у меня есть некоторые значения с разными типами, и я хочу сохранить их на карте.ранее я использовал класс ExtendedString для хранения всех данных и преобразования их с помощью функции шаблона в нужный тип, когда бы мне это ни понадобилось.а затем в моем классе конфигурации был map<ExtendedString,vector<ExtendedString> > для хранения всех ключей в файле конфигурации.вот как выглядит мой класс ExtendedString:

class ExtendedString : public std::string
{
public:
    ExtenedString() : public std::string
    {
    }
    template <class T> ExtenededString(T)
    {
        std::stringstream s;
        *this = s.str();
    }
    template <class T>T as(){
        istringstream s(*this);
        T temp;
        d >> temp;
        return temp;
    }
}

Теперь я хочу проанализировать все значения при загрузке моего конфигурационного файла, а также иметь функцию преобразования в любой возможный тип в случае необходимости.например, если я проанализировал какое-то значение в int, и во время выполнения мне понадобилось это значение в виде строки, я хочу иметь возможность сразу преобразовать его, и, кроме того, я предпочитаю не использовать boost в этом случае, это один из моих базовых классов, и яне хочу связывать повышение с каждым разрабатываемым проектом.

Ответы [ 3 ]

2 голосов
/ 31 мая 2011

Одно классическое решение - boost::any, или массивное union.Но я думаю, что оба этих подхода вызывают больше проблем, чем решают.Что не так с созданием, скажем, класса Config, в котором есть член для каждого параметра конфигурации?

1 голос
/ 31 мая 2011

Я бы порекомендовал использовать boost::any, так как похоже, что он делает то, что вы ищете.Однако, если вы действительно не хотите его использовать, вы можете справиться с этим примерно так.Возможно, это не лучший способ сделать это (это первое, что пришло мне в голову) - в основном это сохранение значения в том виде, в котором оно было у вас, как изначально, так и в виде строки.Если вы попытаетесь использовать get как исходный тип, он вернет это значение, в противном случае он будет использовать std::stringstream, чтобы попытаться преобразовать его.

Примечание: Это не 't обрабатывать копирование / назначение, замените d_data на ваш общий указатель выбора для обработки этого.

#include <string>
#include <sstream>
#include <iostream>

class ConfigValue
{
    class HolderBase
    {
      protected:
        virtual void writeValueToStream(std::ostream& os) const = 0;

      public: 
        virtual ~HolderBase() { }

        template <class Type>
        Type getAs() const
        {
            std::stringstream ss;
            writeValueToStream(ss);

            Type temp;
            ss >> temp;
            return temp;
        }
    };

    template <class Type>
    class Holder : public HolderBase
    {
        Type d_value;

      protected:
        void writeValueToStream(std::ostream& os) const
        {
            os << d_value;
        }

      public:
        Holder(const Type& value)
        : d_value(value)
        {
            std::ostringstream oss;
            oss << value;
        }

        Type get() const
        {
            return d_value;
        }
    };

    HolderBase *d_data;

  public:
    template <class Type>
    ConfigValue(const Type& value)
    : d_data(new Holder<Type>(value))
    {
    }

    ~ConfigValue()
    {
        delete d_data;
    }

    template <class Type>
    Type get() const
    {
        if (Holder<Type> *holder = dynamic_cast<Holder<Type>*>(d_data))
        {
            return holder->get();
        }
        else
        {
            return d_data->getAs<Type>();
        }
    }
};

int main()
{
    ConfigValue cv = 10;

    std::cout << cv.get<std::string>() << std::endl;

    return 0;
}
1 голос
/ 30 мая 2011

Вместо того, чтобы хранить их все в виде строк, вы можете написать класс «Value», а затем написать подклассы для каждого вида значений.

...