在文档boost.geometry它指出为什么boost推荐使用核心函数来使用成员函数?
注:喜欢使用X = bg::get:< 0>(点1);
(相对于X = point1.get < 0>();)
我在升压文档其他地方看到这一点。我的问题是为什么?这是一个最佳实践的东西,一个表演的东西或一些怪癖?这是图书馆的一般规则还是特定的?
在文档boost.geometry它指出为什么boost推荐使用核心函数来使用成员函数?
注:喜欢使用X = bg::get:< 0>(点1);
(相对于X = point1.get < 0>();)
我在升压文档其他地方看到这一点。我的问题是为什么?这是一个最佳实践的东西,一个表演的东西或一些怪癖?这是图书馆的一般规则还是特定的?
它本身不是助推器,而是现代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指出)再一次:它不是特定的提升。
std::swap()
作为游离函数std::begin()
和std::end()
作为游离功能std::hash<>
,std::less<>
,std::greater<>
,std::equal_to<>
类似地提供定制点不在侵入性(但当然不是函数)离线主题:出于兴趣,自定义'std :: less'优先于free'operator <'的用例是什么?你说得对,它提供了一个定制点,但我认为这是一个非常晦涩的问题:你希望你的类型可以通过算法和容器进行比较,但不能用普通人写的代码进行比较;-)是否有一些恼人的后果部分专业化,这意味着有时你必须忍受这一点? –
@SteveJessop自由功能最烦人的事情,我能想到的是[ADL的陷阱](http://stackoverflow.com/questions/2958648/what-are-the-pitfalls-of-adl),即ADL也可以轻松完成DoTheWrongThing(TM)。没有办法“控制”ADL(除了禁止它)。是的,库作家可以(也应该)对此进行防御(通过使用ADL屏障命名空间)。但是函数对象具有不同的属性,它们根据定义不参与ADL。 (我知道Eric Niebler主张这一点,并将其用作Proto0x的设计原则)。 – sehe
我不知道这是否是标准库的设计原则。也许他们只是想要例如使用具体的比较器类型实例化容器类型,而不是必须始终使用特定的实例对象初始化某种“通用函数类型”。 – sehe
对于现有的点类型(由其他人提供),您可以实现一个免费的获取函数,但不能添加get成员函数,因此它更通用。 –
@MarcGlisse,但不会有外部点类型(如果它是从基类派生的)必然有'get'呢?这是唯一的原因吗? – mmdanziger
如果'point1'有一个依赖类型,那么你也不需要写'point1.template get <0>()'。 – Simple