V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dangyuluo
V2EX  ›  C++

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

  •  
  •   dangyuluo · 2019-11-20 11:59:42 +08:00 · 2629 次点击
    这是一个创建于 1590 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设我要写一个 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;
    };
    
    9 条回复    2019-11-20 20:58:56 +08:00
    codehz
        1
    codehz  
       2019-11-20 12:01:43 +08:00
    不用这么麻烦,直接返回值 auto 就可以,反正都上模板了,不会需要分离定义的
    dangyuluo
        2
    dangyuluo  
    OP
       2019-11-20 12:06:20 +08:00
    @codehz 不是分离定义吧?可以讲下这里应该怎样用 auto 么?谢谢
    codehz
        3
    codehz  
       2019-11-20 12:09:55 +08:00
    dangyuluo
        4
    dangyuluo  
    OP
       2019-11-20 12:11:31 +08:00
    @codehz 牛逼,C++14 下能编译。可惜我司还在用 C++11😂

    还是谢谢啦
    codehz
        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 的理由就是避免这一大段东西写好几遍(
    dangyuluo
        6
    dangyuluo  
    OP
       2019-11-20 12:15:23 +08:00
    我想我的错误第一是 decltype 的参数应该是一个具体值而不是两个类相加,第二是返回值要么用 auto 要么明确返回值类型,不能默认用 Complex
    codehz
        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
    不然有些场景可能无法调用
    tyrantZhao
        8
    tyrantZhao  
       2019-11-20 12:57:56 +08:00
    追踪返回类型?
    secondwtq
        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>())> {
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3326 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:44 · PVG 21:44 · LAX 06:44 · JFK 09:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.