如何从C++中定义文件的数据类型?

如何从C++中定义文件的数据类型?,c++,casting,types,C++,Casting,Types,我正在为一个对象创建一个类,该对象应该包含一个值,但是该值将以值、数据类型的形式从外部读取,其中数据类型告诉我如何解释给定的值int、float、double、char等 我想知道是否有可能在运行时进行铸造,以及如何进行铸造。老实说,我有点迷路了,我找到的关于这个主题的信息似乎有点过火 有什么想法吗?谢谢。查找歧视工会,特别是boost::variant,但要点是: struct Value { enum { INT, FLOAT, DOUBLE, CHAR, ETC } type; u

我正在为一个对象创建一个类,该对象应该包含一个值,但是该值将以值、数据类型的形式从外部读取,其中数据类型告诉我如何解释给定的值int、float、double、char等

我想知道是否有可能在运行时进行铸造,以及如何进行铸造。老实说,我有点迷路了,我找到的关于这个主题的信息似乎有点过火


有什么想法吗?谢谢。

查找歧视工会,特别是boost::variant,但要点是:

struct Value {
  enum { INT, FLOAT, DOUBLE, CHAR, ETC } type;
  union {
    int int_;
    float float_;
    double double_;
    char char_;
    etc etc_;
  } value;
};

然后在执行任何操作之前检查类型,并根据存储在其中的内容选择正确的联合成员。

您所描述的是一种变体类型。开始阅读


您可以创建一个类,从文件中读取数据并将其存储在变量中。

我将为每种类型创建一个解析器映射。解析器可以是一个指向函数的指针,该函数接受字符串并返回一个变量。请参阅其他答案。类似以下未经测试的伪代码:

class TypedReader {
  public:
    typedef Variant (*Parser)(const std::string &value);
    Variant readVariant(std::istream &in);
  private:
    std::map<std::string, Parser> parsers;
    // these parsers are added to the "parsers" field above by the constructor
    static Variant intParser(const std::string &value);
    static Variant doubleParser(const std::string &value);
    // and so on
};

Variant TypedReader::readVariant(std::istream &in) {
  // read next (type, value) pair
  std::map<std::string, Parser>::iterator i = parsers.find(type);
  if (i == parsers.end()) {
    // error, type not supported, throw exception or return an invalid variant
  } else {
    return (*i->second)(value);
  }
}

我所说的无效变量是指不包含任何内容的特殊类型。它也可以称为空变量或空变量。正如注释中所指出的,parsers字段也可以是静态的,但是应该以某种静态方式初始化它。例如,它可以封装在另一个具有默认构造函数的类中。

最可扩展的是抽象工厂模式

typedef boost::function<Variant(istream&)> VariantFactory;
std::map< int, VariantFactory > variantFactoryTable;

Variant readVariantFromStream(istream& is)
{
   int type = 0;
   if( is >> type )
   {
       std::map<int, VariantFactory>::const_iterator factIter = 
          variantFactoryTable.find(type);

       if(factIter != variantFactoryTable.end() )
       {
           return factIter->second(is);
       }
       else
       {
           // handle error by throwing or returning a Null
       }
   }
   else
   {
       // handle EOS condition (probably not with exception)
   }
}

如果识别键是固定的,那么解析器成员也可以是静态的。最好指出,无效变量是指我希望向变量添加另一个潜在类型以表示此有效状态,例如在我的答案中向枚举添加无效。但如果不需要这种状态,则抛出异常会更好。@Fred,无效变体正是您所说的。异常的可移植性稍差,否则通常更好。无效变量也可以有其他用途,类似于空指针的用途。解析器成员实际上可以是静态的,我没有想到这一点,因为我是在我的一个支持动态注册新类型的类之后建模这个示例的。