C++箴言:類型轉換時定義非成員函數

來源:互聯網
上載者:User

提要:《C++箴言:聲明為非成員函數的時機》闡述了為什麼只有non-memberfunctions(非成員    《C++箴言:聲明為非成員函數的時機》闡述了為什麼只有 non-member functions(非成員函數)適合於應用到所有 arguments(實參)的 implicit type conversions(隱式類型轉換),而且它還作為一個樣本使用了一個 Rational class 的 operator* function。我建議你在閱讀本文之前先熟悉那個樣本,因為本文進行了針對《C++箴言:聲明為非成員函數的時機》中的樣本做了一個無傷大雅(模板化 Rational 和 operator*)的擴充討論: 
 template<typename T>
class Rational {
public:
Rational(const T& numerator = 0, // see《C++箴言:用傳引用給const取代傳值》for why params
const T& denominator = 1); // are now passed by reference

const T numerator() const; // see《C++箴言:避免返回對象內部構件的控制代碼》for why return
const T denominator() const; // values are still passed by value,
... // Item 3 for why they're const
};

template<typename T>
const Rational<T> operator*(const Rational<T>& lhs,
const Rational<T>& rhs)
{ ... }

    就像在《C++箴言:聲明為非成員函數的時機》中,我想要支援 mixed-mode arithmetic(混合模式運算),所以我們要讓下面這些代碼能夠編譯。我們指望它能,因為我們使用了和 Item 24 中可以工作的代碼相同的代碼。僅有的區別是 Rational 和 operator* 現在是 templates(模板):

 Rational<int> oneHalf(1, 2); // this example is from 《C++箴言:聲明為非成員函數的時機》,
// except Rational is now a template

Rational<int> result = oneHalf * 2; // error! won't compile

    編譯失敗的事實暗示對於模板化 Rational 來說,有某些東西和 non-template(非模板)版本不同,而且確實存在。在《C++箴言:聲明為非成員函數的時機》中,編譯器知道我們想要調用什麼函數(取得兩個 Rationals 的 operator*),但是在這裡,編譯器不知道我們想要調用哪個函數。作為替代,它們試圖斷定要從名為 operator* 的 template(模板)中執行個體化出(也就是建立)什麼函數。它們知道它們假定執行個體化出的某個名為 operator* 的函數取得兩個 Rational<T>
類型的參數,但是為了做這個執行個體化,它們必須斷定 T 是什麼。問題在於,它們做不到。

  在推演 T 的嘗試中,它們會察看被傳入 operator* 的調用的 arguments(實參)的類型。在當前情況下,類型為 Rational<int>(oneHalf 的類型)和 int(2 的類型)。每一個參數被分別考察。

  使用 oneHalf 的推演很簡單。operator* 的第一個 parameter(形參)被聲明為 Rational<T> 類型,而傳入 operator* 的第一個 argument(實參)(oneHalf) 是 Rational<int> 類型,所以 T 一定是 int。不幸的是,對其它參數的推演沒那麼簡單。operator* 的第二個 parameter(形參)被聲明為 Rational<T> 類型,但是傳入 operator* 的第二個 argument(實參)(2) 的 int 類型。在這種情況下,讓編譯器如何斷定
T 是什麼呢?你可能期望它們會使用 Rational<int> 的 non-eXPlicit constrUCtor(非顯式建構函式)將 2 轉換成一個 Rational<int>,這樣就使它們推演出 T 是 int,但是它們不這樣做。它們不這樣做是因為在 template argument deduction(模板實參推演)過程中從不考慮 implicit type conversion functions(隱式類型轉換函式)。從不。這樣的轉換可用於函數調用過程,這沒錯,但是在你可以調用一個函數之前,你必須知道哪個函數存在。為了知道這些,你必須為相關的
function templates(函數模板)推演出 parameter types(參數類型)(以便你可以執行個體化出合適的函數)。但是在 template argument deduction(模板實參推演)過程中不考慮經由 constructor(建構函式)調用的 implicit type conversion(隱式類型轉換)。《C++箴言:聲明為非成員函數的時機》不包括 templates(模板),所以 template argument deduction(模板實參推演)不是一個問題,現在我們在
C++ 的 template 部分,這是主要問題。

  在一個 template class(模板類)中的一個 friend declaration(友元聲明)可以指涉到一個特定的函數,我們可以利用這一事實為受到 template argument deduction(模板實參推演)挑戰的編譯器解圍。這就意味著 class Rational<T> 可以為 Rational<T> 聲明作為一個 friend function(友元函數)的 operator*。class templates(類模板)不依靠 template argument deduction(模板實參推演)(這個過程僅適用於
function templates(函數模板)),所以 T 在 class Rational<T> 被執行個體化時總是已知的。通過將適當的 operator* 聲明為 Rational<T> class 的一個 friend(友元)使其變得容易

原帖地址:http://c.itwaka.com/basic1/39517.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.