简体   繁体   English

使用c ++ stl迭代器而不是传统指针的正确方法是什么?

[英]What is the right way of using c++ stl iterators instead of traditional pointers?

I have the following very basic question. 我有以下非常基本的问题。 I want to use stl iterators instead of traditional C-type pointers for filling an array in a function. 我想使用stl迭代器而不是传统的C类型指针来填充函数中的数组。 By the C-style way I mean the following example: 通过C风格的方式我的意思是以下示例:

void f(double* v, size_t n) {
    for (int i = 0; i < n; i++) 
         v[i] = 10;    /* a more reasonable value in practice! */
}

I would convert this to the C++ style using the iterators as follows: 我会使用迭代器将其转换为C ++样式,如下所示:

void f(vector<double>::const_iterator first, vector<double>::const_iterator last) {
    for(vector<double>::iterator it =  first; it != last; it++)
        *it = 10;
}

But I get compilation errors. 但我得到编译错误。 If I use iterator instead of const_iterator the problem will be solved. 如果我使用iterator而不是const_iterator ,问题就会解决。 However, I was wondering if that is the correct way? 但是,我想知道这是否正确? Because I thought vector.begin() and vector.end() iterators are constant. 因为我认为vector.begin()vector.end()迭代器是常量。

Thanks in advance! 提前致谢!

The difference between 和...之间的不同

const vector<double>::iterator

and

vector<double>::const_iterator

is roughly the same as between double * const v and const double *v : double * const vconst double *v之间大致相同:

  • the first says that the iterator must remain constant, but what it points to can be changed 第一个说迭代器必须保持不变,但它指向的东西可以改变
  • the second says that the iterator itself is changeable, but what it points to is const . 第二个说迭代器本身是可变的,但它指的是const

If you rewrite the function as 如果您将该函数重写为

void f(const vector<double>::iterator first, const vector<double>::iterator last) {
    for(vector<double>::iterator it =  first; it != last; it++)
        *it = 10;
}

it would compile and run correctly. 它会编译并正确运行。

What you see is due to the fact that const_iterator 's correspond roughly to pointers to const. 你看到的是因为const_iterator大致对应于指向const的指针。 So you can change the value of the iterator, ie make it point somewhere else, but you cannot modify what it points to. 因此,您可以更改迭代器的值,即将其指向其他位置,但您无法修改它指向的内容。

This is different from const iterators, which would not allow incrementing or decrementing them. 这与const迭代器不同,后者不允许递增或递减它们。 Here is an example: 这是一个例子:

#include <vector>

int main() {
  std::vector<int> v{ 1, 2, 3 };

  std::vector<int>::const_iterator i = v.begin();
  *i = 10;                                         // ERROR!
  ++i;                                             // OK

  std::vector<int>::iterator const ci = v.begin();
  *ci = 10;                                        // OK
  ++ci;                                            // ERROR!
}
std::fill(my_vector.begin(), my_vector.end(), 10);

Since you're using const_iterator s, you can't modify the vector. 由于您使用的是const_iterator ,因此无法修改向量。 Using non-const iterator s is the right thing to do. 使用非const iterator是正确的做法。

In answer to your last question, vector.begin() and vector.end() have both const_ and non- const_ implementations. 在回答你的上一个问题时, vector.begin()vector.end()同时具有const_和non const_实现。 If your vector is non-const, you'll get a non- const_ iterator. 如果你的vector是非const的,你将获得一个非const_迭代器。 See the documentation for std::vector::begin . 请参阅std :: vector :: begin的文档。

The problem is that your functions takes const_iterator s but your loop needs an iterator , since you want to modify the data. 问题是你的函数需要const_iterator但你的循环需要一个iterator ,因为你想修改数据。 The solution is of course to let your function take iterator s right away, since it is obviously meant to modify the range. 解决方案当然是让你的函数立即使用iterator ,因为它显然意味着修改范围。

This doesn't have anything to do with what vector.begin() returns. 这与vector.begin()返回的内容没有任何关系。 For a const object or reference they will return const_iterator s, otherwise they'll return iterator s. 对于const对象或引用,它们将返回const_iterator ,否则它们将返回iterator s。 But your function definitely needs iterator s, since it modifies the values in the range passed to it. 但是你的函数肯定需要iterator ,因为它修改了传递给它的范围内的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM