如何使用c++在数组中存储不同的值类型

how can I store diffrent value types in an array using c++?

本文关键字:类型 存储 何使用 c++ 数组      更新时间:2023-10-16

我想在配置类中实现的一些功能遇到了问题,我有一些不同类型的值,我想将它们存储在映射中。以前,我使用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,它是我的基类之一,我不想将boost链接到我正在开发的每个项目。

一个经典的解决方案是boost::any,或大规模的union。但我认为这两种方法造成的麻烦都多于解决的麻烦。创建一个Config类,每个配置选项都有成员,这有什么错?

我建议使用boost::any,因为它听起来像是你想要的。然而,如果你真的不想使用它,你可能可以这样处理它。这可能不是最好的方法(这是我想到的第一件事)——基本上是将值存储在原来的类型中,并作为字符串。如果您尝试将get作为原始类型,它将返回该值,否则,它将使用std::stringstream尝试转换它。

注意:这不处理复制/分配,请将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;
}

您可以编写一个"Value"类,然后为每种值编写子类,而不是将它们全部存储为字符串。