我提出的解决方案是使用“中性类型”动态地(如DavidRodríguez - dribeas所述)进行类型转换。
优势:
- 的解决方案是通用的:使用一个新的类型时,你不需要那么任何特别的事情。
至于弊端
代码:
struct Wrapper
{
// get the "neutral type" value
virtual string getValue() const = 0;
template <typename U> Wrapper* clone() const;
};
template <typename T>
struct WrapperT: Wrapper
{
explicit WrapperT(T v): value(v)
{
}
virtual string getValue() const
{
// use streams to conversion to neutral value, but
// other better method would be suitable
ostringstream strm;
strm << value;
return strm.str();
}
T value;
};
template <typename U> Wrapper* Wrapper::clone() const {
U value;
istringstream strm(getValue());
strm >> value;
return new WrapperT<U>(value);
}
编辑:
为了更好的性能解决方案,如果只使用数字类型,我们可以通过long double
为 “中立型” 转变string
:
template <typename T>
double long WrapperT<T>::getValue() const
{
return value;
}
template <typename U> Wrapper* Wrapper::clone() const {
return new WrapperT<U>(getValue());
}
我们是否想避免积分浮动仅使用整数类型时的点转换?在这种情况下,该解决方案将是复杂一点:
- 在
clone()
功能取决于U
模板创建两个getValue()
虚拟函数,一个用于积分和另一个用于浮点,
- 选择所需
getValue()
功能参数类型(目标类型)。
如果有人在下一行“t->克隆()',你希望发生什么? (其中'foo'是完全不相关的类型) –
Yakk
转换指导者模板显式WrapperT(const WrapperT &);'? –
jrok
@jrok:构造函数不知道真实类型。他想从一个指针转换为基类到派生类型。 –