简体   繁体   中英

How to put a templated class into a list and save the type

If I have the following class:

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

and I create a Converter class that can be called like this:

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

Assuming the converter template class would need the type of the object and the type of the field we're going to pass to it.

This isn't too big of a problem, you can just convert the string back to the original type and call the 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;
  ...
};

The problem is putting these converter classes into a container of some kind. Perhaps something like:

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

First thoughts went to a abstract base class, but then you can't get the original type out of the base class, which means you can't do the string conversion.

Any ideas would be much appreciated.

EDIT:

Slight clarification. The idea is to create a map with converters of different types, like this:

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

This line will not compile:

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

The problem is that Converter* is not a valid type. Converter<Animal, int>* is. You can not create pointer without specifying the template parameters. This also solves your other problem - you don't have to store the type in any other way but in the type of the pointer.

You probably need to define a base class for all your converters, and let your template converters derived from your base class.

Most of the time, interface can help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM