2

模板类实例如何接收不同类型的同一模板类的另一个实例作为其某些函数成员的参数?(我很难用更简单的方式表达我的问题,对此我感到非常抱歉。)

这是一个工作代码。我创建了一个类并将其命名为 MyClass。它在其 operator= 和 operator+ 成员函数上接受相同类型(即 int)的相同模板类。

#include <iostream>
using namespace std;

template<class T>
class MyClass {
protected:
  T __val;
public:
  MyClass();
  MyClass(T val): __val(val) {}
  void operator= (const MyClass<T>& r)
  {
    __val = (T)r.__val;
  }
  const MyClass<T>& operator+ (const MyClass<T>& r)
  {
    return *(new MyClass<T>(__val + (T)r.__val));
  }
  T retval() {return __val;}
};

int main()
{
  MyClass<int> myclass1(1);
  MyClass<int> myclass2(2);
  MyClass<int> myclass3 = myclass1 + myclass2;
  cout << myclass3.retval() << endl;
  return 0;
}

我对 operator= 和 operator+ 的参数的 __val 成员进行了类型转换,目的如下:

int main()
{
  MyClass<int> myclass1(1);
  MyClass<double> myclass2(2.5);
  MyClass<int> myclass3 = myclass1 + myclass2;
  cout << myclass3.retval() << endl;
  return 0;
}

显然我会得到一个错误。我不能仅仅因为MyClass<int>::operator+想要MyClass<int>参数而不是MyClass<double>. 我知道我可以重载另一个接受 的 operator+ MyClass<double>,但我也想使用其他数字类型,例如 float、single 等。为所有这些类型创建重载函数会使我的代码更大,我显然不想这样做发生。

我必须从 MyClass 更改什么才能使我的第二个主要功能正常工作?

4

3 回答 3

2

您需要一个模板成员operator+。此外,它应该返回一个值,而不是引用:

template<class T>
class MyClass 
{
 public:
  template <typename T2>
  MyClass operator+ (const MyClass<T2>& r) const { return _val + r.retval(); }

  T retval() const {return _val;}

  // as before
};

请注意,这将返回与表达式中的 LHS 相同类型的值operator+operator+请注意,作为非成员二元运算符实现会更好。但是你必须实现一些编译时逻辑来确定返回类型:

template <typename T1, typename T2>
MyClass< ?? > operator+(const MyClass<T1>& lhs, const MyClass<T1>& rhs)
{
  return lhs.retval() + rhs.retval();
}

where??应该被一个 compile 构造替换以选择基于T1and的类型T2。据推测,这将是这两种类型中的一种。这是一个 C++11 示例:

template <typename T1, typename T2>
auto operator+(const MyClass<T1>& lhs, const MyClass<T1>& rhs)->decltype(lhs.retval()+rhs.retval())
{
  return lhs.retval() + rhs.retval();
}

这样做的好处是返回类型的确定与 LHS 或 RHS 上的内容无关。

于 2013-09-08T15:11:32.773 回答
0

Casting 比 dot 具有更强的优先级,即代替

(T)r.__val

你必须写

(T) (r.__val)

更好,使用static_cast. 因此,定义operator +

template<class S>
MyClass<T> operator+ (const MyClass<S>& r) {
   return MyClass<T>(__val + (static_cast<S> (r.__val)) );
}

或者根本不使用显式转换:

template<class S>
MyClass<T> operator+ (const MyClass<S>& r) {
   return MyClass<T>(__val + r.__val);
}

最好让 retval 返回一个 const T &,在 operator + 的实现中使用 retval(),并使 operator + 成为非成员非友元:

template<class T>
class MyClass {
private:
  T m_val;
public:
  MyClass(T val): m_val(val) {}
  const T & retval () const {return m_val;}
};

template<class T1, class T2>
auto operator+ (const MyClass<T1>& r1, const MyClass<T2> & r2)
-> MyClass < std::remove_const < std::remove_reference <
   decltype ( r1.retval () + r2.retval () ) 
> > > {
    return r1.retval () + r2.retval ();
}
于 2013-09-08T15:15:29.737 回答
0

你可以这样写:

template<typename _Ty> MyClass<T> operator+ (const MyClass<_Ty>& r) {
   return MyClass<T>(__val + (static_cast<_Ty> (r.__val)) );
}

提供成员函数。但要更普遍地支持它,请执行以下操作:

template<typename _T,typename _Ty> MyClass<_T> operator+ (const Myclass<_T>& p,const MyClass<_Ty>& r) {
       return MyClass<T>(p.__val + (static_cast<_T> (r.__val)) );
    }

不幸的是,你必须__val公开

于 2013-09-08T15:38:43.697 回答