运算符重载多个模板

时间:2011-01-27 09:37:31

标签: templates operator-overloading c++

template <class T>
class A
{
    private:
        T m_var;
    public:
        operator T () const { return m_var; }
        ........
}

template<class T, class U, class V>
const A<T> operator+ (const U& r_var1, const V& r_var2)
{ return A<T> ( (T)r_var1 + (T)r_var2 ); }

这个想法是为这些情况重载+运算符一次(而不是三次): number + A,A + number,A + A(其中number是T型,与m_var相同)。 一个有趣的例子是如果m_var是例如int和r_var很长。

任何帮助都将受到高度赞赏。谢谢。

4 个答案:

答案 0 :(得分:6)

实现所需要的常见模式是在相反的方向上实际执行它:提供从T到模板的隐式转换,并仅定义模板的运算符。

template <typename T>
struct test {
   T m_var;
   test( T const & t ) : m_var(t) {}   // implicit conversion
   test& operator+=( T const & rhs ) {
      m_var += rhs.m_var;
   }
   friend test operator+( test lhs, test const & rhs ) { // *
      return lhs += rhs;
   }
};
// * friend only to allow us to define it inside the class declaration

关于成语的几个细节:operator+被声明为朋友,只允许我们在类花括号内定义一个自由函数。在查找编译器时,这有一些优点,因为如果其中一个参数已经是test,它只会考虑该运算符。

由于构造函数是隐式的,因此调用test<int> a(0); test<int> b = a + 5;将转换为等效的test<int> b( a + test<int>(5) );相反,如果切换到5 + a

operator+operator+=表示,通过按值获取第一个参数,在单行中实现。如果运营商更复杂,那么这将为两个运营商提供单一的实施。

答案 1 :(得分:2)

运算符+的问题是你有3个模板参数,一个用于返回类型和强制转换,但编译器无法自动解析该参数。

你也会在演员阵容中犯下一些罪恶。

如果在命名空间中将operator +定义为自由模板函数,则可以利用它,它只对该命名空间中定义的类型有效。

在你的命名空间中,我将使用T和U

来定义
template< typename T >
T operator+( const T & t1, const T& t2 )
{
   T t( t1 );
   t += t2; // defined within T in your namespace
   return t;
}

template< typename T, typename U >
T operator+( const T& t, const U& u )
{
    return t + T(u);
}

template< typename T, typename U >
T operator+( const U& u, const T& t )
{
   return T(u) + t;
}
除非a和b中的一个类型位于定义模板的命名空间中,否则此模板不会覆盖

a + b。

答案 2 :(得分:1)

不应该重载op +用于你不了解的无关类型 - 这可能会破坏已经存在的完美工作代码。你应该将你的类作为op + overload的至少一个参数。

如果您不希望从T到A&lt; T&gt;的implicit conversion,那么我只会写出重载。如果您遵循“@ to @ =”重载模式,这是最清晰的代码,并且根本不长,

template<class T>
struct A {
  explicit A(T);

  A& operator+=(A const &other) {
    m_var += other.m_var;
    // This could be much longer, but however long it is doesn't change
    // the length of the below overloads.
    return *this;
  }
  A& operator+=(T const &other) {
    *this += A(other);
    return *this;
  }

  friend A operator+(A a, A const &b) {
    a += b;
    return a;
  }
  friend A operator+(A a, T const &b) {
    a += A(b);
    return a;
  }
  friend A operator+(T const &a, A b) {
    b += A(a);
    return b;
  }

private:
  T m_var;
};

答案 3 :(得分:0)

C ++ 0x解决方案

template <class T>
class A
{
    private:
        T m_var;
    public:
        operator T () const { return m_var; }
        A(T x): m_var(x){}
};

template<class T,class U, class V>
auto operator+ (const U& r_var1, const V& r_var2) -> decltype(r_var1+r_var2)
{
    return  (r_var1 + r_var2 );
}

int main(){

    A<int> a(5);
    a = a+10;
    a = 10 + a;
}

不幸的是,将template<class T,class U, class V>更改为template<class U, class V>会在gcc 4.5.1上调用segmentation fault。我不知道为什么?