2014-01-21 62 views
4

在文檔boost.geometry它指出爲什麼boost推薦使用核心函數來使用成員函數?

注:喜歡使用X = bg::get:< 0>(點1);
(相對於X = point1.get < 0>();)

我在升壓文檔其他地方看到這一點。我的問題是爲什麼?這是一個最佳實踐的東西,一個表演的東西或一些怪癖?這是圖書館的一般規則還是特定的?

+1

對於現有的點類型(由其他人提供),您可以實現一個免費的獲取函數,但不能添加get成員函數,因此它更通用。 –

+0

@MarcGlisse,但不會有外部點類型(如果它是從基類派生的)必然有'get'呢?這是唯一的原因嗎? – mmdanziger

+2

如果'point1'有一個依賴類型,那麼你也不需要寫'point1.template get <0>()'。 – Simple

回答

14

它本身不是助推器,而是現代C++ API設計。

  • 通過不需要成員函數,您可以調整自己的類,甚至是第三方庫類型以使用您選擇的boost Api。 (這樣,您可以將第三方庫中的類型序列化爲Boost序列化存檔)。

  • 此外,通過使函數具有自由函數,依賴性得到了改進的解耦。例如:fusion/tuple.hpp不需要依賴任何與IO相關的內容,因爲流操作是免費功能,因此可以在單獨的頭文件中聲明(並定義):fusion/tuple_io.hpp

  • 它也有助於封裝,因爲默認情況下,免費的功能都沒有friend S中的主機類(並因此無法訪問私有成員)。

  • 免費功能可以「做正確的事」的基礎上ADL:

    using std::swap; 
    swap(a, b); // will lookup `swap` in the namespaces that declare the parameter types 
    

    (其他幾個命名空間也可用於查找)

  • 最後,自由功能可一般服務的一組類型,不需要與面向對象相關(繼承相關)。這樣,免費功能可以避免重複代碼。

編輯解決的,爲什麼你應該更喜歡非會員語法,如果同時存在問題:

  • 它適用於類型沒有成員函數
  • 它不需要在模板代碼.template歧義(如@simple指出)
  • 再一次:它不是特定的提升。

    • C++ 03已std::swap()作爲遊離函數
    • C++ 11引入std::begin()std::end()作爲遊離功能
    • std::hash<>std::less<>std::greater<>std::equal_to<>類似地提供定製點不在侵入性(但當然不是函數
+0

離線主題:出於興趣,自定義'std :: less'優先於free'operator <'的用例是什麼?你說得對,它提供了一個定製點,但我認爲這是一個非常晦澀的問題:你希望你的類型可以通過算法和容器進行比較,但不能用普通人寫的代碼進行比較;-)是否有一些惱人的後果部分專業化,這意味着有時你必須忍受這一點? –

+0

@SteveJessop自由功能最煩人的事情,我能想到的是[ADL的陷阱](http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl),即ADL也可以輕鬆完成DoTheWrongThing(TM)。沒有辦法「控制」ADL(除了禁止它)。是的,庫作家可以(也應該)對此進行防禦(通過使用ADL屏障命名空間)。但是函數對象具有不同的屬性,它們根據定義不參與ADL。 (我知道Eric Niebler主張這一點,並將其用作Proto0x的設計原則)。 – sehe

+0

我不知道這是否是標準庫的設計原則。也許他們只是想要例如使用具體的比較器類型實例化容器類型,而不是必須始終使用特定的實例對象初始化某種「通用函數類型」。 – sehe

相關問題