为什么std :: pair会暴露成员变量?

guo*_*guo 52 c++ encapsulation stl

http://www.cplusplus.com/reference/utility/pair/,我们知道std::pair有两个成员变量,firstsecond.

为什么STL设计者决定公开两个成员变量,firstsecond不是提供a getFirst()和a getSecond()

Che*_*Alf 94

对于原始的C++ 03 std::pair,访问成员的函数没有任何用处.

从C++ 11及更高版本开始(我们现在在C++ 14,C++ 17快速出现)std::pair是一个特例std::tuple,std::tuple可以有任意数量的项目.因此,有一个参数化的getter是有意义的,因为发明和标准化任意数量的项名称是不切实际的.因此,你可以使用std::get同样的std::pair.

因此,设计的原因是历史性的,即当前std::pair是向更一般性演变的最终结果.


在其他新闻中:

关于

"据我所知,如果将两个成员变量封装在上面并给出一个getFirst();和更好的话会更好getSecond()

不,那是垃圾.

这就像说锤子总是更好,无论你是用钉子钉,用螺钉固定,还是修剪一块木头.特别是在最后一种情况下,锤子不是一种有用的工具.锤子可能非常有用,但这并不意味着它们总体上"更好":这只是胡说八道.

  • 我特此授予+1对于像java一样的getter和简单数据成员的设置者的盲目奉献的劝告. (58认同)
  • 使用两个功能将允许从空基类优化中受益.这就是Boost压缩对的工作方式. (6认同)
  • @ Cheersandhth. - 阿尔夫在实践中不能使用EBO只有一个项目.要做到这一点,你必须直接从maybe-empty-class继承,例如`std :: vector`必须从`allocator_type`继承.那将是**坏**.想象一下,如果分配器有一个虚函数`size()`...现在`std :: vector :: size()`会覆盖它.**坏**.所以在实践中你让`std :: vector`有一个类型为`Impl`的成员变量,它是一个继承自`allocator_type`的结构,并且有一个成员(可能是vector的begin指针或结束指针). (4认同)
  • 至少从1997年开始这是一个常见的习惯用法(参见http://www.cantrip.org/emptyopt.html解释了虚拟覆盖器的问题和解决方案)和`compressed_pa​​ir`类型是一种简单的方法来利用它.我不能为我的生活想象你是如何保持不知道这个成语的;-) (4认同)
  • @ Cheersandhth.-Alf压缩对用于例如`unique_ptr`的实现,以消除删除者的空间; 同样,它们可以用来摆脱空间的集装箱分配器.在容器中,可能存在多个潜在的无状态对象,例如比较函数对象等."unique_ptr"等的向量可能是这种优化有意义的更现实的例子; 还考虑了内存限制算法.不幸的是,它似乎使它更难编译器优化代码,例如用于分配. (3认同)

Som*_*ken 29

如果认为获取或设置值需要额外的逻辑(改变某些内部状态),则getter和setter通常很有用.然后可以将其轻松添加到方法中.在这种情况下std::pair,仅用于提供2个数据值.没有更多,没有更少.因此,添加吸气剂和设定器的详细程度将毫无意义.

  • @ Cheersandhth.-Alf我说的是(非静态的)成员函数,它们是getter和setter,`std :: get`是_not_是`std :: pair`的成员函数,因此它是无效的. (4认同)
  • @ Cheersandhth.-Alf我很抱歉你无法理解我的评论.但是,如果你有兴趣争论而不仅仅是抨击其他人,你或许可以指出我希望我扩展的一些领域,这样我们就可以完全理解对方 (3认同)

Ili*_*llo 13

原因是不需要对数据结构施加真正的不变量,因为std::pair模型是两个元素的通用容器.换言之,类型的对象std::pair<T, U>被假定为有效的任何可能的firstsecond类型的元件TU分别.同样,其元素价值的后续突变也不能真正影响std::pair本身的有效性.

Alex Stepanov(STL的作者)在评论容器(即一个元素的容器)时,在他的" 使用组件进行高效编程"课程中明确地介绍了这个一般设计原则. singleton

因此,尽管原则本身可以成为争论的源泉,但这也是形成原因的原因std::pair.

  • 正是!`std :: pair`只是一个数据集合.因此,它应该是一个`struct`用`public`成员. (5认同)

dav*_*bak 9

如果人们认为抽象是保证用户免于设计选择和现在或将来的那些选择的变化,那么Getters和setter是有用的.

"现在"的典型示例是setter/getter可能具有验证和/或计算值的逻辑 - 例如,使用setter作为电话号码,而不是直接暴露字段,以便您可以检查格式; 对集合使用getter,以便getter可以向调用者提供成员值(集合)的只读视图.

"未来的变化" 的规范(虽然不好)的例子是Point- 你应该公开xygetX()getY()?通常的答案是使用getter/setter,因为在将来的某个时候,您可能希望将内部表示 从笛卡尔更改为极地,并且您不希望您的用户受到影响(或让他们依赖于该设计决策) .

在这种情况下std::pair- 意图是这个类现在并且永远直接表示两个且恰好两个值(任意类型),并根据需要提供它们的值.而已.这就是为什么设计使用直接成员访问,而不是通过getter/setter.

  • @CodyGray一个人都有的东西完全倒退,因为它看起来对我来说,引用变化的坐标空间从用户_precisely_绝缘,只提到存储/处理内部,而用户继续看到和发送直角坐标正是因为他们做了之前. (2认同)

Die*_*ühl 8

可以说,std::pair拥有访问者功能以访问其成员会更好!特别是对于退化的情况,std::pair可能有一个优势.例如,当至少一个类型是空的非final类时,对象可以更小(空基可以成为不需要获得其自己的地址的基础).

当时std::pair发明了这些特殊情况没有被考虑(我不确定当时的工作文件草案中是否允许空基础优化).从语义角度来看,没有太多理由拥有访问器功能:显然,访问者需要为非const对象返回可变引用.结果,访问器不提供任何形式的封装.

另一方面,它使得优化器[稍微]难以看到当使用访问器函数时发生了什么,例如因为引入了额外的序列点.我可以想象孟李和亚历山大斯捷潘诺夫甚至衡量是否存在差异(我也没有).即使他们没有,直接提供对成员的访问肯定不比通过访问器功能慢,而反过来不一定是真的.

我不是决策的一部分,C++标准不具有合理性,但我这是一个深思熟虑的决定,使成员公共数据成员.