2016-04-06 21 views
-1

这是我写的用于开始使用类模板的代码。如何调用此类程序中涉及类模板的单参数构造函数?

#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

@πάνταῥεῖ错误出现在+运算符函数中。导致错误的整数值导致错误,因为单参数构造函数未被调用。我需要知道如何在使用类模板时使用C2 = 3 + C1。谢谢 – hcoder

+2

你的代码从骨头上是有严重缺陷的。停止使用原始指针,新手入门。 –

+0

您应该删除大部分代码,并从'T real,imag;'重新开始。从长远来看,这将节省大量时间。 –

回答

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

+0

所以我们最终将string_view标准化了吗?我不知道! – SergeyA

+1

@SergeyA它是已经被合并到C++ 17中的基础V1的一部分。 –

相关问题