Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中常量迭代器和非常量迭代器的区别是什么+;STL?_C++_Stl_Iterator_Constants - Fatal编程技术网

C++ C+中常量迭代器和非常量迭代器的区别是什么+;STL?

C++ C+中常量迭代器和非常量迭代器的区别是什么+;STL?,c++,stl,iterator,constants,C++,Stl,Iterator,Constants,常量迭代器和迭代器之间有什么区别?您会在哪里使用它们?常量迭代器不允许您更改它们指向的值,常规的迭代器会这样做 和C++中的所有东西一样,总是首选 const ,除非有一个很好的理由使用正则迭代器(即,你想使用它们不是 const 来改变指向的值)。 < P>它们应该是非常自我解释的。如果迭代器指向类型为T的元素,则const_迭代器指向类型为“const T”的元素 它基本上等同于指针类型: T* // A non-const iterator to a non-const element.

常量迭代器
迭代器
之间有什么区别?您会在哪里使用它们?

常量迭代器
不允许您更改它们指向的值,常规的
迭代器
会这样做


和C++中的所有东西一样,总是首选 const ,除非有一个很好的理由使用正则迭代器(即,你想使用它们不是<代码> const <代码>来改变指向的值)。

< P>它们应该是非常自我解释的。如果迭代器指向类型为T的元素,则const_迭代器指向类型为“const T”的元素

它基本上等同于指针类型:

T* // A non-const iterator to a non-const element. Corresponds to std::vector<T>::iterator
T* const // A const iterator to a non-const element. Corresponds to const std::vector<T>::iterator
const T* // A non-const iterator to a const element. Corresponds to std::vector<T>::const_iterator
T*//非常量元素的非常量迭代器。对应于std::vector::迭代器
T*const//非常量元素的常量迭代器。对应于常量std::vector::迭代器
const T*//常量元素的非常量迭代器。对应于std::vector::const_迭代器

常量迭代器总是指向同一个元素,因此迭代器本身就是常量。但是它指向的元素不必是常量,因此可以更改它指向的元素。
常量迭代器是指向常量元素的迭代器,因此虽然迭代器本身可以更新(例如递增或递减),但它指向的元素不能更改。

尽可能使用常量迭代器,没有其他选择时使用迭代器const_迭代器不允许修改它指向的元素,这在const类方法中很有用。它还允许您表达您的意图。

不幸的是,STL容器的许多方法都将迭代器作为参数,而不是常量迭代器作为参数。因此,如果你有一个常量迭代器,你不能说“在这个迭代器指向的元素之前插入一个元素”(在我看来,这样说在概念上并不违反常量)。无论如何,如果要这样做,必须使用std::advance()boost::next()将其转换为非常量迭代器。例如,boost::next(container.begin(),std::distance(container.begin(),我们想要的常量迭代器)。如果容器std::list,则该调用的运行时间将为O(n)

因此,在任何“合乎逻辑”的地方添加常量的通用规则在涉及STL容器时就不那么通用了


但是,boost容器使用常量迭代器(例如boost::无序的\u map::erase()。因此,当您使用boost容器时,您可以是“const agressive”。顺便问一下,有人知道STL容器是否会被修复或何时修复吗?

好的,让我先用一个非常简单的例子解释一下,而不使用常量迭代器 考虑我们收集了随机整数集合“随机数据”< /P>
for(vector::iterator i=randomData.begin();i!=randomData.end();++i)*i=0;

对于(vector::const_迭代器i=randomData.begin();i!=randomData.end();++i)可以最小可运行示例

非常量迭代器允许您修改它们指向的内容:

std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();
*it = 1;
assert(v[0] == 1);
const
生成
this
const,它生成
this->v
const

您通常可以使用
auto
将其忘记,但是如果您开始传递这些迭代器,则需要考虑它们作为方法签名

与常量和非常量非常相似,您可以轻松地从非常量转换为常量,但不能反过来转换:

std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();

// non-const to const.
std::vector<int>::const_iterator cit = it;

// Compile time error: cannot modify container with const_iterator.
//*cit = 1;

// Compile time error: no conversion from const to no-const.
//it = ci1;
std::vector v{0};
std::vector::iterator it=v.begin();
//非常量对常量。
std::vector::const_迭代器cit=it;
//编译时错误:无法使用常量迭代器修改容器。
//*cit=1;
//编译时错误:没有从常量到无常量的转换。
//it=ci1;

使用哪一个:类似于
const int
vs
int
:只要你可以使用const迭代器(当你不需要用它们修改容器时),就更喜欢使用它们,以便更好地记录你的阅读意图而不需要修改。

在一个完美的世界中就是这样。但C++的const只和编写代码的人一样好:(可变的存在是非常好的原因,很少使用,而且看谷歌代码搜索,似乎有合理的使用百分比。关键字是一个非常强大的优化工具,它不像删除它会提高const的正确性。(咳嗽指针咳嗽和咳嗽参考咳嗽)更像是一个强大的黑客。在我所见过的所有使用“mutable”关键字的例子中,除了一个以外,其他所有的都是一个准确的指示器,表明代码编写得很糟糕,需要mutable作为黑客来绕过缺陷。它确实有合法的用途,比如在const类中缓存长时间计算的结果。另一方面这几乎是我在C++开发中使用了一个可变的唯一的时间。使用conthyIdor的一个通用的例子是迭代器是一个rconst“const迭代器总是指向同一个元素”。这是不正确的。怎么回事?请注意缺少的下划线。我正在将一个类型为const std::vector::iterator的变量与std::vector::const_iterator进行对比。在前一种情况下,迭代器本身是const,因此不能修改,但它引用的元素可以自由修改。啊,我明白了。是的,我缺少下划线。@JohnDibling Upvoted解释
常量迭代器
常量迭代器
之间的微妙之处。这可能是一个意见问题。在
向量
deque
的情况下,插入一个元素会使所有现有的迭代器无效,这不是非常
常量
。但我明白你的观点。这样的操作受containe的保护r
const
-
const std::vector<int> v{0};
std::vector<int>::const_iterator cit = v.begin();
// Compile time error: cannot modify container with const_iterator.
//*cit = 1;
class C {
    public:
        std::vector<int> v;
        void f() const {
            std::vector<int>::const_iterator it = this->v.begin();
        }
        void g(std::vector<int>::const_iterator& it) {}
};
std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();

// non-const to const.
std::vector<int>::const_iterator cit = it;

// Compile time error: cannot modify container with const_iterator.
//*cit = 1;

// Compile time error: no conversion from const to no-const.
//it = ci1;