代码之家  ›  专栏  ›  技术社区  ›  baol

模板类的子类型的operator+

  •  1
  • baol  · 技术社区  · 16 年前

    我有一个定义子类型的模板类。我正试图定义二进制 operator+ 作为模板函数,但编译器无法解析 运算符+ .

    #include <iostream>
    template<typename other_type> 
    struct c {
      c(other_type v) : cs(v) {}
      struct subtype { subtype(other_type v) : val(v) {} other_type val; } cs;
    };
    
    template<typename other_type>
    typename c<other_type>::subtype operator+(const typename c<other_type>::subtype& left,
                          const typename c<other_type>::subtype& right)
    { return typename c<other_type>::subtype(left.val + right.val); }
    
    // This one works
    // c<int>::subtype operator+(const c<int>::subtype& left,
    //          const c<int>::subtype& right)
    // { return c<int>::subtype(left.val + right.val); }
    
    int main()
    {
      c<int> c1 = 1;
      c<int> c2 = 2;
      c<int>::subtype cs3 = c1.cs + c2.cs;
      std::cerr << cs3.val << std::endl;
    }
    

    我认为原因是因为编译器(G++4.3)无法猜测模板类型,所以它正在搜索 operator+<int> 而不是 运算符+ .

    原因是什么?你能提出什么优雅的解决方案?

    1 回复  |  直到 16 年前
        1
  •  4
  •   Johannes Schaub - litb    16 年前

    你的怀疑是正确的。编译器不知道什么 other_type 是。它不能从论点中推断出来。这种形式往往过于松散,无法提供所需的信息。考虑

    template<typename other_type> 
    struct c {
      c(other_type v) : cs(v) {}
      typedef int subtype;
    };
    

    如果你通过 int 然后任何一个 c<T> 因为他们都有 int . 在嵌套类的特定情况下,它可能是可能的,但即使这样它也不是唯一的。想象一下 c<float> 你可以放一个 typedef c<int> subtype; 然后两者兼而有之 c<float>::subtype 和 c<int>::subtype 会合适的。

    早在标准时间之前,就有一个模板问题的列表,特别是约翰·斯派克(JohnSpicer)确实经历了这些问题,并发明了合理的解决方案。这就是这样一个问题,人们发现它不值得麻烦。你总是明确地需要提供论点,这是从来没有推导出来的。

    你可以把你的代码改成这个

    template<typename other_type> 
    struct subtype { 
      subtype(other_type v) : val(v) {}
      other_type val; 
    };
    
    template<typename other_type> 
    struct c {
      c(other_type v) : cs(v) {}
      subtype<other_type> cs;
    };
    
    template<typename other_type>
    subtype<other_type> operator+(const subtype<other_type>& left,
                          const subtype<other_type>& right)
    { return subtype<other_type>(left.val + right.val); }
    

    或者这个

    template<typename other_type> 
    struct c {
      c(other_type v) : cs(v) {}
      struct subtype { 
       subtype(other_type v) : val(v) {} other_type val; 
    
        /* note: don't forget friend! */
        friend subtype operator+(const subtype& left,
                          const subtype& right)
        { return subtype(left.val + right.val); }
      } cs;
    };
    
    推荐文章