2011-08-05 80 views
16

在此article on defining your own extensions to ::std::error_code筆者建議使用此代碼:爲了能夠從自己的錯誤常數系統錯誤類型轉換向std名稱空間注入專門化可以嗎?

namespace std 
{ 
    template <> 
    struct is_error_code_enum<http_error> 
    : public true_type {}; 
} 

這是合理的嗎?將東西放入std命名空間總是讓我感到緊張。有沒有更好的方法來實現目標?如果沒有這一切,是否有一部分標準表明這總是可以做的?

回答

23

是的,特(用戶定義類型)現有STD類型是你被允許放在std命名空間,只要專業化符合原始模板的要求唯一事情。

請參閱C++ 0x草案中的17.6.4.2.1。

當然,禁止使用新的類型,函數重載和其他任何東西。但是允許現有模板的專業化。

+1

你有更好的答案,但@ Steve314包括在某些情況下,你絕對必須這樣做的重要細節。我可能會等待幾個小時(只是基於一般原則),然後可能會接受這一個。 – Omnifarious

8

這不僅僅是好的 - 在某些情況下這是必不可少的。你不應該做的是在std中定義全新的函數/類/模板。

std::swap特別是一個常見和簡單的事情來專業化。有些類需要這樣做以允許高效的交換,基本上交換私有引用來交換內部信息,而不是使用默認的臨時和分配實現。

編輯

通過ildjarn註解中提到的ADL - Argument Dependent name Lookup。 Wikipedia頁面在「Interfaces」和「Criticism」部分特別提到了std::swap

Stroustrup的第13.5.2節(特別版)包括std::swap專業化的示例。從報價...

less()swap()這些專業標準庫(16.3.9,16年3月20日)被使用。另外,它們是廣泛適用的技術的例子。

我一直讀到作爲指示std::swap是專業化是做正確的事,我從來沒有足夠的擔心ADL懷疑這一點,但它可能有一個在標準中使用之間的」差距庫「和」廣泛適用的技術「 - 該技術不應使用來專門處理std::swap以處理不在std中的類型。

也有可能有一個樣式問題,在特殊版首次發佈時還沒有決定。 AFAIK,Stroustrup增加了一些額外的附錄並應用了一些勘誤表,但否則不會對內容進行實質性修改。

基於維基百科頁面,有混合專業化和ADL的混合的潛在問題 - 有時你可以得到不明確性,防止任何查找。如果將這兩種技術混合使用,則只會發生,而ADL無論如何都會導致語義問題。但是這個觀點只會導致「根本不使用ADL」,但ADL確實存在是有原因的。

嗯,是的,ADL的存在是有原因的 - 所以非成員函數和運算符與時間一起可以看到類型。但是std::swap不與一個特定類型相關聯 - 它是通用的,只有特定的特定類型與特定類型相關聯。如果你想讓std::swap可見,你需要std命名空間。 ADL沒有必要做這項工作,正如維基百科頁面指出的那樣,對ADL有批評。

這是什麼意思,基本上,我不知道。我有我的理性。他們不一定同意更廣泛的風格規則。當然,這個評論證明,它不是必不可少的專門std::swap - 你可以提供自己的獨立swap並依靠ADL來代替。也許這是首選。

我可能會回來,並在我檢查後再次編輯。

+2

'std :: swap'應該不**爲專用或重載 - 相反,應該在與交換類型相同的名稱空間中放置一個'swap'自由函數,並讓ADL完成剩下的工作。 – ildjarn

+0

@ildjarn - 謝謝 - 我不確定你是否正確,但看到編輯。 – Steve314

+0

ADL在主要的編譯器中廣泛地被打破了一段時間,所以'std :: swap'專業化已成爲標準實踐。但是,使用現代的,更符合標準的編譯器,解決方法不再是必需的。 – ildjarn

相關問題