27

这里有人最近提到Scott Meyers 的文章说:

  • 更喜欢iteratorspdf链接const_iterators)。

其他人评论说这篇文章可能已经过时了。我想知道你的意见是什么?

这是我的:这篇文章的主要观点之一是你不能在 a 上擦除或插入const_iterator,但我认为用它作为反对const_iterators. 我认为const_iterators它的全部意义在于您根本不修改范围,既不是通过替换它们的值来修改元素本身,也不是通过插入或擦除来修改范围。还是我错过了什么?

4

6 回答 6

22

我完全同意你的看法。我认为答案很简单:在 const 值是正确使用的地方使用 const_iterators,反之亦然。在我看来,那些反对 const_iterators 的人通常必须反对 const ......

于 2009-04-19T11:34:32.177 回答
9

这是一种稍微不同的看待它的方式。当您将它作为指针传递给特定集合并且您也在传递集合Const_iterator时,几乎没有任何意义。Meyer 先生特别指出不能与集合实例的大多数成员函数一起使用。在这种情况下,您将需要一个普通的. 但是,如果您没有集合的句柄,则两者之间的唯一区别是您可以修改an指向的内容,而不能修改 a 引用的对象。const_iteratoriteratoriteratorconst_iterator

iterator所以......当您将集合和位置传递给算法时,您想要使用该集合。基本上,签名如下:

void some_operation(std::vector<int>& vec, std::vector::const_iterator pos);

没有多大意义。隐含的声明是some_operation可以自由修改底层集合但不允许修改什么pos引用。这没有多大意义。如果你真的想要这个,那么pos应该是一个偏移量而不是一个迭代器。

另一方面,STL 中的大多数算法都基于由一对迭代器指定的范围。iterator集合本身永远不会被传递,因此和之间的区别在于const_iterator集合中的值是否可以通过迭代器进行修改。没有对集合的引用,分离是非常清楚的。

希望这让事情变得像泥巴一样清晰;)

于 2009-04-19T15:31:53.230 回答
3

我不认为需要特别关注迈耶的这一特殊陈述。当您想要一个非修改操作时,最好使用const_iterator. 否则,使用普通的iterator. 但是,请注意一件重要的事情:永远不要混合迭代器,即迭代器const与迭代器non-const。只要你知道后者,你应该没问题。

于 2009-04-19T11:40:16.720 回答
3

我通常更喜欢 constness,但最近遇到了一个与 const_iterators 相关的难题,这混淆了我的“始终使用 const 是可能的”理念:

MyList::const_iterator find( const MyList & list, int identifier )
{
    // do some stuff to find identifier
    return retConstItor;
}

由于传入 const 列表引用要求我只使用 const 迭代器,现在如果我使用 find,我无法对结果做任何事情,但查看它,即使我想要做的只是表示 find 不会改变列表通过了。

那么,我想知道 Scott Mayers 的建议是否与这样的问题有关,因为这些问题无法逃避 const-ness。据我了解,由于一些内部细节,您不能(可靠地)使用简单的强制转换 un-const const_iterators。这也(可能同时)是问题所在。

这可能是相关的:How to remove constness of const_iterator?

于 2009-10-12T21:57:22.900 回答
3

C++98

我认为需要考虑到 Meyers 声明指的是 c++98。今天很难说,但如果我没记错的话

  • 为非 const 容器获取 const_iterator 根本不容易
  • 如果你有一个 const_iterator 你几乎不可能使用它,因为容器成员函数的大多数(全部?)位置参数都应该是迭代器而不是 const_iterators

例如

std::vector<int> container;

本来需要

static_cast<std::vector<int>::const_iterator>(container.begin())

得到一个 const_iterator,它会大大夸大一个简单的 .find ,即使你有你的结果之后

std::vector<int>::const_iterator i = std::find(static_cast<std::vector<int>::const_iterator>(container.begin()), static_cast<std::vector<int>::const_iterator>(container.end()),42);

将无法使用您的 std::vector::const_iterator 插入到向量或任何其他预期位置迭代器的成员函数中。并且没有办法从 const 迭代器中获取迭代器。为此,不存在(存在?)铸造方法。

因为 const iterator 并不意味着容器不能改变,而只是指向的元素不能改变(const iterator 相当于指向 const 的指针),在这种情况下真的是一大堆废话.

今天恰恰相反。

const 迭代器很容易使用 cbegin 等。即使对于非 const 容器和所有(?)占据位置的成员函数都有 const 迭代器作为它们的参数,因此不需要任何转换。

std::vector<int> container;                
auto i = std::find(container.cbegin(), container.cend(), 42); 
container.insert(i, 43); 

那么曾经是什么

更喜欢迭代器而不是 const_iterators

今天真的真的应该

更喜欢 const_iterators 而不是迭代器

因为第一个只是历史执行缺陷的产物。

于 2017-08-22T19:25:32.873 回答
2

通过阅读该链接,Meyers 似乎从根本上说 interator 比 const_interator 更好,因为您无法通过 const_iterator 进行更改。

但如果这是他所说的,那么迈耶斯实际上是错误的。这正是为什么 const_iterator 比 iterator 更好的原因,因为这是您想要表达的。

于 2009-04-19T18:21:31.637 回答