假设我要写一个 Complex 类,底层存储类别写成模版参数。我可以实现Complex<int> + Complex<int>
并得到正确返回,下一步想支持Complex<int> + Complex<double>
或者任何可以相加的数值类型。这时候我需要确认int
和double
哪个占用更多空间,来确定operator+(...)
的返回类型。
这时候应该怎么做到?我猜测应该是和下面的代码类似,但是用 C 久了不太会用decltype
,望大神指点一二。谢谢
代码如下:
template <typename T = int>
class Complex{
public:
Complex()
: real(0), imag(0){}
Complex(T r, T i)
: real(r), imag(i){}
template <typename U>
Complex operator+(const Complex<U>& rhs ){
Complex<decltype(T+U)> ret(real + rhs.real, imag + rhs.imag);
return ret;
}
friend std::ostream& operator<<(std::ostream& out, const Complex& c){
out << "(" << c.real << ", " << c.imag << ")" << std::endl;
return out;
}
private:
T real;
T imag;
};
1
codehz 2019-11-20 12:01:43 +08:00
不用这么麻烦,直接返回值 auto 就可以,反正都上模板了,不会需要分离定义的
|
3
codehz 2019-11-20 12:09:55 +08:00
|
5
codehz 2019-11-20 12:13:18 +08:00 1
简单解释一下
template <typename U> auto operator+(const Complex<U>& rhs ){ return Complex<decltype(std::declval<T>()+std::declval<U>())>{ real + rhs.real, imag + rhs.imag }; } declval 这里是为了生成对应类型的实例(当然这里也可以用 T{} + U{},为了普适性我们通常用 declval,因为不是所有类型都能 0 参数初始化的) 为啥需要这一步呢,因为只有实例才能进行+运算啊 然后用 auto 的理由就是避免这一大段东西写好几遍( |
6
dangyuluo OP 我想我的错误第一是 decltype 的参数应该是一个具体值而不是两个类相加,第二是返回值要么用 auto 要么明确返回值类型,不能默认用 Complex
|
7
codehz 2019-11-20 12:22:58 +08:00 1
是这样,另外还有一个错误就是没 template<typename U> class Complex<U> 加友元,(
(说到友元,这个函数我觉得应该要加一个 const & noexcept(或者做成友元 template <typename U> auto operator+(const Complex<U>& rhs ) const & noexcept 不然有些场景可能无法调用 |
8
tyrantZhao 2019-11-20 12:57:56 +08:00
追踪返回类型?
|
9
secondwtq 2019-11-20 20:58:56 +08:00
@dangyuluo 可以改成 auto operator+(const Complex<U>& rhs) -> Complex<decltype(std::declval<T>()+std::declval<U>())> {
|