2014-01-21 57 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

相关问题