这是我为编写类模板而编写的代码。
#include<iostream>
using namespace std;
template<class T>
class Complex
{
T *real,*imag;
public:
Complex(T a)
{
real=new T;
imag=new T;
*real=a;
*imag=0;
}
Complex(T a,T b)
{
real=new T;
imag=new T;
*real=a;
*imag=b;
}
Complex()
{
real=new T;
imag=new T;
*real=0;
*imag=0;
}
template<class R>
friend ostream& operator<<(ostream &out,Complex<R> &C);
template<class R>
friend istream& operator>>(istream &in,Complex<R> &C);
template<class R>
friend Complex<R> operator +(Complex<R> a,Complex<R> b);
};
template<class R>
ostream& operator<<(ostream &out,Complex<R> &C)
{
out<<"The number is "<<*C.real<<"+"<<*C.imag<<"i"<<endl;
return out;
}
template<class R>
istream& operator>>(istream &in,Complex<R> &C)
{
cout<<"Enter the number ";
in>>*C.real>>*C.imag;
return in;
}
template<class R>
Complex<R> operator +(Complex<R> a,Complex<R> b)
{
Complex<R> temp;
*temp.real=*a.real+*b.real;
*temp.imag=*a.imag+*b.imag;
return temp;
}
int main()
{
Complex<float> C1,C2(4.2,6.8),C3,C4;
C1=5;
C3=3+C1;
C4=C2+C3;
cout<<C1;
cout<<C2;
cout<<C3;
cout<<C4;
}
此代码一切正常,除非我尝试使用像'3 + C2'这样的整数值时显示错误。如果在不使用“3 + C2”模板的情况下考虑相同的代码,则调用友元函数运算符+(复杂a,复数b),并将3复制到对象a,该对象调用单个参数构造函数,3将分配给实际的部分。复杂的课程。如何在使用类模板时发生同样的事情?当使用类模板时,如果将数字传递给operator +()函数而不是Complex对象,如何调用单个参数构造函数?
答案 0 :(得分:1)
类似
template<class R>
Complex<R> operator +(Complex<R>, Complex<R>);
类型R
是从每个函数参数独立推导出来的;扣除必须成功,推导出的类型必须匹配才能使用。由于3不是Complex
,因此扣除失败并且不考虑过载。
有两种方法可以解决这个问题。一种是使用非模板朋友:
template<class T>
class Complex {
// ...
friend Complex operator+(Complex a, Complex b) {
// ...
}
};
这实例化为非模板友元函数,很高兴考虑隐式转换。
另一种方法是提供额外的重载,这些重载仅从一个参数推导出来:
template<class T> struct identity { using type = T; };
template<class T> using nondeduced_t = typename identity<T>::type;
template<class R>
Complex<R> operator +(nondeduced_t<Complex<R>>, Complex<R>) { /* ... */ }
template<class R>
Complex<R> operator +(Complex<R>, nondeduced_t<Complex<R>>) { /* ... */ }
这是std::basic_string_view
采取的方法。
顺便说一下,你的实施工作严重受损。它会泄漏内存,就像没有明天一样 - 并且没有理由首先动态分配T
。