如何将模板化类放入列表中并保存类型

  • 本文关键字:列表 类型 保存 c++
  • 更新时间 :
  • 英文 :


如果我有以下类:

class Animal {
  ...
  int GetSize() const { return _size; }
  void SetSize(int size) { _size = size; }
  ...
private:
  int _size;
};

我创建了一个可以像这样调用的转换器类:

Animal* elephant = new Animal(...);
Converter* c = new Converter<Animal, int>(&Animal::GetSize, &Animal::SetSize);
c->Set(elephant, "50");

假设转换器模板类需要对象的类型和字段的类型,我们将传递给它。

这不是太大的问题,您可以将字符串转换回原始类型并调用 setter:

template <typename ObjectType, typename ValueType>
class Converter {
  ...
  void Set(ObjectType* obj, ValueType value) {
    std::stringstream ss(value);
    T newValue;
    ss >> newValue;
    (obj->*_setter)(newValue);
  }
  ...
  typedef void (ObjectType::*SetterType)(ValueType);
  SetterType setter;
  ...
};

问题是将这些转换器类放入某种容器中。 也许像这样:

std::map<std::string, Converter*> fields;
fields["size"] = new Converter<Animal, int>(&Animal::GetSize, &Animal::SetSize);

首先想到的是抽象基类,但后来您无法从基类中获取原始类型,这意味着您无法进行字符串转换。

任何想法将不胜感激。

编辑:

稍微澄清一下。 这个想法是创建一个包含不同类型的转换器的地图,如下所示:

fields["size"] = new Converter<Animal, int>(&Animal::GetSize, &Animal::SetSize);
fields["growth"] = new Converter<Animal, double>(&Animal::GetGrowth, &Animal::SetGrowth);

此行不会编译:

Converter* c = new Converter<Animal, int>(&Animal::GetSize, &Animal::SetSize);

问题是Converter*不是有效的类型。 Converter<Animal, int>*是。如果不指定模板参数,则无法创建指针。这也解决了您的另一个问题 - 您不必以任何其他方式存储类型,而是以指针的类型存储类型。

您可能需要为所有转换器定义一个基类,并让模板转换器派生自基类。

大多数时候,界面可以提供帮助。

最新更新