【发布时间】:2021-08-05 18:28:35
【问题描述】:
class Base{
public:
template <typename T> T getValueAs()
{
//should return (T)this->getValue()
}
template <typename T> void setValueFrom(T val)
{
//should call this->setValue((Impl::value_type)val)
}
};
template<typename T> class Impl : public Base {
public:
virtual void setValue(const T& val){ ... }
virtual T getValue() const{ ... }
protected:
T value;
};
//also some very speficic impl would be
class NumVal : public Base<int>{
};
我想把它用作:
Impl<float> var;
var.setValue(42.0f);
Base* baseVar = (Base*)&var;
int convertedVal = baseVar->getValueAs<int>(); // should return (int)(42.0f)
我知道我们不能覆盖模板成员函数,这里的限制是Base类不知道Impl类的确切值类型,有没有替代方法来实现类似的东西?
否则,我需要在基类上实现非常具体的转换,以便在后代类上覆盖:
class Base{
public:
virtual std::string getString() = 0;
virtual int getInt() = 0;
virtual bool getBool() = 0;
};
所以我需要的只是Base::get<T>()
【问题讨论】:
-
为什么
Base不是带有非模板方法的模板? -
在 CRTP 模式中,您的 Base 将是一个模板,而 Impl 将是
template<typename T> class Impl : public Base<Impl<T>>。如果您这样做,您将能够在BasesgetValue()中投降。虽然不清楚为什么要这样做,因为getValue将始终在派生类中被覆盖。 -
问的不同:为什么首先使用继承?假设您可以覆盖模板方法,您将无法多态地使用它们,因为它们具有不同的参数/返回类型
-
Base 不能是模板类,因为我需要在“用户”不知道 var 所持有的确切类型的情况下传递它,我只是希望它像
void* -
是否可以从
Impl<Bar>到getValueAs<Foo>?编辑:是的,这实际上是示例显示的内容。
标签: c++ templates reflection type-conversion polymorphism