Одно из решений здесь - перевернуть вызов и использовать виртуальную функцию. Но сначала давайте перепишем UserValueProvider::getValue
, поскольку перегрузка только для возвращаемых типов запрещена.
class UserValueProvider {
template <class T> struct tag { };
int getValue(tag<int>) const { return 5; }
bool getValue(tag<bool>) const { return true; }
std::string getValue(tag<std::string>) const { return "foobar"; }
public:
template <class T>
T getValue() const {
return getValue(tag<T>{});
}
};
Теперь мы можем вызвать uvp.getValue<T>()
, чтобы получить соответствующее значение. Затем добавьте виртуальную функцию к NC
и ее производным классам:
class NC {
public:
virtual void setValueFrom(UserValueProvider &uvp) = 0;
};
template <typename T>
class TC: public NC {
private:
T value;
public:
void setValue(T value) {
this->value = value;
}
void setValueFrom(UserValueProvider &uvp) override {
setValue(uvp.getValue<T>());
}
};
И вуаля, вы можете просто передать свой UserValueProvider
своему стертому типу NC
, и он будет отправляться правильно.
void setUserValue(UserValueProvider *uvp, NC *obj) {
obj->setValueFrom(*uvp);
}
Посмотреть в прямом эфире на Wandbox