我应该更喜欢迭代器而不是 const_iterators 吗?

发布于 2024-07-16 18:35:29 字数 548 浏览 2 评论 0原文

最近有人提出了 Scott Meyers 的文章,其中写道:

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

这是我的:这篇文章的要点之一是你不能在 const_iterator 上删除或插入,但我认为用它作为反对 const_iterators 的论点很有趣。 我认为 const_iterators 的全部要点在于,您根本不修改范围,既不修改元素本身(通过替换其值),也不修改范围(通过插入或删除)。 或者我错过了什么?

Someone here recently brought up the article from Scott Meyers that says:

  • Prefer iterators over const_iterators (pdf link).

Someone else was commenting that the article is probably outdated. I'm wondering what your opinions are?

Here is mine: One of the main points of the article is that you cannot erase or insert on a const_iterator, but I think it's funny to use that as an argument against const_iterators. I thought the whole point of const_iterators it that you do not modify the range at all, neither the elements themselves by substituting their values nor the range by inserting or erasing. Or am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

爱给你人给你 2024-07-23 18:35:29

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

I totally agree with you.
I think the answer is simple:
Use const_iterators where const values are the right thing to use, and vice versa.
Seems to me that those who are against const_iterators must be against const in general...

帅气称霸 2024-07-23 18:35:29

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

所以...每当您将集合和集合中的位置传递给算法时,您都需要使用迭代器。 基本上,签名如下:

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

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

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

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

Here's a slightly different way to look at it. Const_iterator almost never makes sense when you are passing it as a pointer into a specific collection and you are passing the collection as well. Mr. Meyer was specifically stating that const_iterator cannot be used with most member functions of a collection instance. In that case, you will need a plain-old iterator. However, if you don't have a handle to the collection, the only difference between the two is that you can modify what is pointed to by an iterator and you can't modify the object referenced by a const_iterator.

So... you want to use iterator whenever you are passing a collection and position into the collection to an algorithm. Basically, signatures like:

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

don't make a whole lot of sense. The implicit statement is that some_operation is free to modify the underlying collection but is not allowed to modify what pos references. That doesn't make much sense. If you really want this, then pos should be an offset instead of an iterator.

On the flip side, most of the algorithms in the STL are based on ranges specified by a pair of iterators. The collection itself is never passed so the difference between iterator and const_iterator is whether the value in the collection can be modified through the iterator or not. Without a reference to the collection, the separation is pretty clear.

Hopefully that made things as clear as mud ;)

棒棒糖 2024-07-23 18:35:29

我通常更喜欢 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 const_iterators。 这也是(也许同时存在)问题。

这可能是相关的:如何删除 const_iterator 的常量性?

I generally prefer constness, but recently came across a conundrum with const_iterators that has confused my "always use const were possible" philosophy:

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

Since passing in a const list reference required that I only use const iterators, now if I use the find, I cannot do anything with the result but look at it even though all I wanted to do was express that find would not change the list being passed in.

I wonder perhaps, then, if Scott Mayers advice has to do with issues like this where it becomes impossible to escape const-ness. From what I understand, you cannot (reliably) un-const const_iterators with a simple cast because of some internal details. This also (perhaps in conjunction) be the issue.

this is probably relevant: How to remove constness of const_iterator?

如此安好 2024-07-23 18:35:29

我认为不需要特别关注迈耶的这一特定声明。 当您想要非修改操作时,最好使用const_iterator。 否则,使用普通的迭代器。 但是,请注意一件重要的事情:切勿将迭代器(即 const 迭代器)与非 const 迭代器混合使用。 只要您意识到后者,就应该没问题。

I don't think this particular statement of Meyer's needs to be taken with special concern. When you want a non-modifying operation, it is best to use a const_iterator. Otherwise, use an ordinary iterator. However, do note the one important thing: Never mix iterators i.e. const ones with non-const ones. As long as you are aware of the latter, you should be fine.

ぶ宁プ宁ぶ 2024-07-23 18:35:29

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_iterator

今天确实应该更

优先使用 const_iterator 而不是迭代器

因为第一个迭代器只是历史实现缺陷的产物。

C++98

I think one needs to take into account that Meyers statement refers to c++98. Hard to tell today, but if I remember right

  • it simply was not easy to get a const_iterator for a non const container at all
  • if you got a const_iterator you could have hardly made any use of it since most (all?) position arguments for container member functions were expected to be iterators and not const_iterators

e.g.

std::vector<int> container;

would have required

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

to get a const_iterator, which would have considerably inflated a simple .find
and even if you had your result then after

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);

there would have been no way to use your std::vector::const_iterator for insertion into the vector or any other member function that expected iterators for a position. And there was no way to get a iterator from a const iterator. No way of casting existed (exists?) for that.

Because const iterator does not mean that the container could not be changed, but only that the element pointed to could not been changed (const iterator being the equivalent of pointer to const) that was really a big pile of crap to deal with in such cases.

Today the opposite is true.

const iterators are easy to get using cbegin etc. even for non const containers and all (?) member functions that take positions have const iterators as their arguments so there is no need for any conversion.

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

So what once was

Prefer iterators over const_iterators

today really really should be

Prefer const_iterators over iterators

since the first one is simply an artifact of historical implementation deficits.

梦归所梦 2024-07-23 18:35:29

通过我对该链接的阅读,迈耶斯似乎从根本上说 interator 比 const_interator 更好,因为你无法通过 const_iterator 进行更改。

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

By my reading of that link, Meyers appears to be fundamentally saying that interator's are better than const_interator's because you cannot make changes via a const_iterator.

But if that is what he is saying then Meyers is in fact wrong. This is precisely why const_iterator's are better than iterator's when that is what you want to express.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文