C++问题:嵌套模版中如何确定 T+U 的类型?

2019-11-20 11:59:42 +08:00
 dangyuluo

假设我要写一个 Complex 类,底层存储类别写成模版参数。我可以实现Complex<int> + Complex<int>并得到正确返回,下一步想支持Complex<int> + Complex<double>或者任何可以相加的数值类型。这时候我需要确认intdouble哪个占用更多空间,来确定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;
};
2657 次点击
所在节点    C++
9 条回复
codehz
2019-11-20 12:01:43 +08:00
不用这么麻烦,直接返回值 auto 就可以,反正都上模板了,不会需要分离定义的
dangyuluo
2019-11-20 12:06:20 +08:00
@codehz 不是分离定义吧?可以讲下这里应该怎样用 auto 么?谢谢
codehz
2019-11-20 12:09:55 +08:00
dangyuluo
2019-11-20 12:11:31 +08:00
@codehz 牛逼,C++14 下能编译。可惜我司还在用 C++11😂

还是谢谢啦
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 的理由就是避免这一大段东西写好几遍(
dangyuluo
2019-11-20 12:15:23 +08:00
我想我的错误第一是 decltype 的参数应该是一个具体值而不是两个类相加,第二是返回值要么用 auto 要么明确返回值类型,不能默认用 Complex
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
不然有些场景可能无法调用
tyrantZhao
2019-11-20 12:57:56 +08:00
追踪返回类型?
secondwtq
2019-11-20 20:58:56 +08:00
@dangyuluo 可以改成 auto operator+(const Complex<U>& rhs) -> Complex<decltype(std::declval<T>()+std::declval<U>())> {

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/621335

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX