2010-09-02 28 views
13

我想爲我的班級重載operator<<。我應該將這個重載的定義添加到std命名空間嗎? (因爲ostream operator<<std命名空間的一部分)或者我應該把它留在全局命名空間中嗎?非成員運算符重載應該放在哪裏?

簡而言之:

class MyClass { 

}; 

namespace std { 
    ostream& operator<< (ostream& Ostr, const MyClass& MyType) {} 
} 

OR

class MyClass { 

}; 

std::ostream& operator<< (std::ostream& Ostr, const MyClass& MyType) {} 

哪個更合適,爲什麼?預先感謝您的回覆。

回答

25

您應該將運算符重載放在與您的類相同的命名空間中。

這將允許使用參數相關查找(當然,實際上,因爲ostream是在命名空間std,過載超載也將如果你把它命名空間std發現重載解析過程中發現的運營商,但有沒有理由這樣做)。

從良好設計實踐的角度來看,操作符重載比類接口ostream更接近類接口的一部分,因此它與您的類屬於相同的命名空間(另請參閱Herb Sutter的Namespaces and the Interface Principle)。

從編寫符合標準和可移植代碼的角度來看,您不能將運算符重載放入名稱空間std。雖然可以將用戶定義實體的模板特化添加到名稱空間std,但不能添加其他函數重載。

+1

+1此外,強制性鏈接:http://en.wikipedia.org/wiki/Argument-dependent_lookup – 2010-09-02 03:31:16

+0

考慮到山姆對標準的迴應和引用,最後一句是否真正正確。 – Chubsdad 2010-09-02 03:46:20

+3

@chubsdad:是的,我認爲是這樣的:你可以增加專業化;你不能添加重載。 – 2010-09-02 03:48:51

6

不要添加到標準名稱空間。 原因:如果每個人都這樣做了,那麼標準名稱空間就會有大量名稱衝突,這會破壞名稱空間的用途。

你的目標是讓你的班級成爲「ostream-able」。它不需要在標準名稱空間中進行。只要它在你的班級宣佈的任何名稱中,你都很好。將它放入標準名稱空間將是不好的做法。

+1

它破壞了用於C++標準庫代碼的'std'命名空間的目的。哪個用戶代碼不是。 – 2010-09-02 03:32:00

6

不要將它添加到std名稱空間,請將它放在與您的類相同的名稱空間中。命名空間的目的是防止衝突。該標準說

17.4.3.1保留名稱

這是未定義一個C++程序 除非另有規定 內 空間std添加聲明或定義, std命名空間或命名空間。程序可以將任何標準 庫模板的 專用模板添加到名稱空間標準。的未定義的行爲 一個標準庫 模板結果 這種專業化(完全或 部分),除非聲明取決於外部聯動 的 用戶定義的名稱和,除非專門滿足 爲 原始標準庫的要求模板。