C++模板類的轉化構造函數能否進行隱式調用??

有一個模板類型的複數類,其中對double類型用轉換構造函數轉換為複數類,然後重載』+『運算符計算複數加法,代碼如下

#include &
using namespace std;
template &
class Complex
{
public:
Complex() { real = 0; imag = 0; }
Complex(T r, T i) { real = r; imag = i; }
Complex& (double r) {
real = r; imag = 0;
}
Complex(const Complex c) {
real = c.real;
imag = c.imag;
}
friend ostream operator &<&< &(ostream output, Complex& c);
friend istream operator &>&> &(istream input, Complex& c);
template &
friend Complex& operator + (Complex& c1, Complex& c2);
private:
T real;
T imag;
};
template&
istream operator &>&> (istream input, Complex& c)
{
input &>&> c.real &>&> c.imag;
return input;
}
template&
Complex& operator + (Complex& c1, Complex& c2)
{
Complex& c;
c.real = c1.real + c2.real;
c.imag = c1.imag + c2.imag;
return c;
}
int main()
{
Complex& c1, c2, c3;
cout &<&< "請輸入第一個數:"; cin &>&> c1;
cout &<&< "請輸入第二個數:"; cin &>&> c2;
cout &<&< "C1+C2=" &<&< c1 + c2; c3 = c1 + 2.5; return 0; }

這裡c1+2.5無法通過編譯,提示沒有匹配的操作符,而

c3=c1+Complex&(2.5);

就可以,如何進行轉換構造函數的隱式調用??


你的加法的聲明是

template&
Complex& operator + (Complex& c1, Complex& c2)

你寫c1+2.5的話,他不知道那個N是什麼,因為2.5可以有很多種解讀方法。所以正確的做法應該是,只允許同類型的Complex&互相計算,然後同時允許不同類型的Complex&和Complex&互相轉換,這樣你的需求就滿足了。不要把這兩件事情合在同一個函數里。

也就是說

template&
struct Complex
{
template&
operator Complex&();
};

template&
Complex& operator+ (Complex& c1, Complex& c2);


Complex& c;

c+2.5;

c+Complex&(2.5);

上面兩條語句的差別在於前者『想要』使用隱式類型轉換,而後者使用顯示類型轉換。

使用類模板構造對象時,需要顯式地指定類模板的實參,因而無法進行隱式類型轉換。

函數模板支持實參演繹(deduction,模板參數可由用戶傳遞的實參來決定),故使用時無需顯式地指定實參。註:此處也不允許隱式類型轉換。

解決原則:函數調用類型與已聲明的操作符類型相匹配。

解決方案:

1.將2.5強制轉換為Complex&使用;

2.增加template&

Complex& operator+ (Complex&, N)方法。


這個問題恰好在好幾年前碰到過。下面是記憶中的原因:

C++在看一個函數調用時,做的事情可以分成幾個階段:

*先找到所有的candidate函數

*在candidate函數函數集合中找viable的函數

*在viable的函數集合中找best fit

best fit的集合只有一個元素時才能編譯正確。

你的編譯問題錯在第一個階段。

解決的方法是引入:

friend Complex& operator + (Complex& c1, T r);

friend Complex& operator + (T r, Complex& c1);

是的,沒錯。很麻煩。

於是可以引入宏。比如:

#define OP_COMPLEX_PRIMARY_DECL(op)

friend Complex& operator op (Complex& c1, T r);

friend Complex& operator op (T r, Complex& c1);

OP_COMPLEX_PRIMARY_DECL(+)

通過類似的方式增加+, -, ...等等操作的支持。


推薦閱讀:

求一本或者幾本比較詳細介紹C++11的書,《C++ Primer》是否合適?
如何評價Andrei Alexandrescu提出的c++ policy-based design?
如何提升 C++ Trie 樹的存取效率?
如何評價 Herb Sutter 的 C++ 提案:metaclasses?
輪子哥的C++為什麼學的這麼好?請分享一下學習C++秘訣?

TAG:模板 | C | 計算機語言 |