
假设我要写一个 Complex 类,底层存储类别写成模版参数。我可以实现Complex<int> + Complex<int>并得到正确返回,下一步想支持Complex<int> + Complex<double&g;或者任何可以相加的数值类型。这时候我需要确认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 简单解释一下 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 是这样,另外还有一个错误就是没 template<typename U> class Complex<U> 加友元,( (说到友元,这个函数我觉得应该要加一个 const & noexcept(或者做成友元 template <typename U> auto operator+(const Complex<U>& rhs ) const & noexcept 不然有些场景可能无法调用 |
8 geminikingfall 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>())> { |