如何使(使用不同模板类型的对象)A * B和B * A给出相同的结果,其中结果的类型根据通常的C ++类型提升规则确定< /强>
例如:
int main()
{
number<float> A(2.0f);
number<double> B(3.0);
A*B; // I want 6.0 (double)
B*A; // I want 6.0 (double)
return 0;
}
目前,我只能将相同模板类型的对象相乘。例如,像这样:
template<typename T>
class number
{
public:
number(T v) : _value(v) {}
T get_value() const { return _value; }
number& operator*=(const number& rhs)
{
_value *= rhs.get_value();
return *this;
}
private:
T _value;
};
template<typename T>
inline number<T> operator*(number<T> lhs, const number<T>& rhs)
{
lhs *= rhs;
return lhs;
}
编辑:或者,如在答案中,我可以将不同模板类型的对象相乘,但始终返回与lhs相同的类型。有没有办法改为返回一个类型由标准类型提升规则决定的对象?
编辑2:我想尽可能避免使用C ++ 11功能。
答案 0 :(得分:2)
你需要模板化,例如rhs
参数:
template<typename T>
class number
{
public:
number(T v) : _value(v) {}
T get_value() const { return _value; }
template<class E>
number& operator*=(const number<E>& rhs)
{
_value *= rhs.get_value();
return *this;
}
private:
T _value;
};
template<class T, class E, class RET = decltype(T()*E())>
number<RET> operator*(number<T>& lhs, const number<E>& rhs)
{
return lhs.get_value()*rhs.get_value();
}
答案 1 :(得分:1)
您需要operator*()
template<typename T>
class number {
public:
// ...
template<typename U>
number& operator*=(const number<U>& rhs) {
// ...
}
// ...
};
对于二元运算符
也是如此template<typename T,typename U>
inline number<T> operator*(number<T> lhs, const number<U>& rhs) {
lhs *= rhs;
return lhs;
}
答案 2 :(得分:1)
您可以使用std::common_type<>
获取返回所需的类型。例如
template<typename X>
struct number
{
// ...
template<typename Y>
number(number<Y> const&other); // needed in line 1 below
template<typename Y>
number&operator=(number<Y> const&other); // you may also want this
template<typename Y>
number&operator*=(number<Y> const&other); // needed in line 2 below
template<typename Y>
number<typename std::common_type<X,Y>::type> operator*(number<Y> const&y) const
{
number<typename std::common_type<X,Y>::type> result=x; // 1
return result*=y; // 2
}
};
我遗漏了模板化构造函数和operator*=
的实现。
不幸的是,std::common_type
是C ++ 11,您希望避免使用这些原因。如果您只使用内置类型(double
,float
,int
等),则可以轻松实现自己的common_type
版本。但是,如果你想进行复杂的元模板编程,强烈建议继续使用C ++ 11 - 它已经有4年了,并且大部分都是向后兼容的。