为什么STL为std :: container :: begin和std :: container :: end函数提供了一个const重载?

时间:2015-11-29 13:31:35

标签: c++ c++11 stl iterator

记住使用迭代器的任何STL容器。

以下内容有效:

iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;

现在我不明白为什么第二行存在。有人可以提供一个很好的例子,其中iterator begin();不起作用而且const_iterator cbegin();无法取代......请求const_iterator begin();

2 个答案:

答案 0 :(得分:2)

在语言中可能没有地方你不能给出不同的名字;这只是善意的一点,有点像size()上的length()std::string

cbegin容器上工作时,记住使用const是PITA,因此const_iterator begin() const很有用。与此同时,当我明确有兴趣获得const迭代器时,如果没有cbegin,我必须做一些像((const std::vector<int> &)vec).begin()那样令人费解的事情,这肯定少了比vec.cbegin()可读/可写。

现在,你可以争辩说,有些地方很少需要这样的善意行为(并且更好地扩展 - 支持常规/反向/常量迭代器的所有组合快速使接口爆炸),我会当然同意你的意见。

顺便说一句,让const_iterator begin避免需要其他小工具来使基于范围的for循环在const个对象上正常工作。

答案 1 :(得分:2)

首先,有一个简单的历史原因:原始C ++标准没有使用cbegin(),只有两个begin()重载。有人认为,有时将const_iterator s添加到非const序列并添加cbegin()cend()(尽管begin()和{end() { {1}} 成员实际上是不明智的:如果他们只是非成员函数,我们会好得多。也就是说,如果在引入const时删除了begin() cbegin()重载,那么很多代码都会被破坏。

从实际的角度来看,同样需要非constconst重载:

  • 在普通代码中使用begin()cbegin()可以完成更改对象const时实际执行此操作会非常烦人/ LI>
  • 更重要的是,在通用(模板化)代码中,序列可以是const或非const,有必要使用一些舞蹈来使用正确的重载。