如果我有以下类:
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>*
是。如果不指定模板参数,则无法创建指针。这也解决了您的另一个问题 - 您不必以任何其他方式存储类型,而是以指针的类型存储类型。
您可能需要为所有转换器定义一个基类,并让模板转换器派生自基类。
大多数时候,界面可以提供帮助。