为什么我不能将迭代器应用于接受 const_iterator 引用的函数?

Why can't I apply an iterator to a function which accepts a reference of const_iterator?

本文关键字:iterator 引用 函数 const 不能 迭代器 应用于 为什么      更新时间:2023-10-16

这是代码。

#include <vector>
void moveIterator(std::vector<char>::const_iterator& v) {
    v++;
}
int main() {
    std::vector<char> v;
    std::vector<char>::iterator iter = v.begin();
    moveIterator(iter);
}

编译失败。这是错误。

 candidate function not viable: no known conversion from 'std::vector<char>::iterator' (aka '__normal_iterator<char *, std::vector<char, std::allocator<char> > >') to 'std::vector<char>::const_iterator &' (aka '__normal_iterator<const char *, std::vector<char, std::allocator<char> > > &') for 1st argument

但是如果我删除参数中的&,它可以工作,如下所示:

void moveIterator(std::vector<char>::const_iterator v) {  // no &
    v++;
}

似乎我无法将iterator应用于接受const_iterator引用的函数,为什么?

> 出于同样的原因,您不能用std::vector<char>调用f(std::string&)

在大多数实现中,

  • std::vector<char>::const_iterator
  • std::vector<char>::iterator

是两个不同的类,并且不可能从一个类转换为另一个类(非常量(引用。

您可以做的是将moveIterator定义为模板:

template<class InputIt>
void moveIterator(InputIt& it) {
    ++it;
}
std::vector<int> v;
auto it = v.begin();
auto cit = v.cbegin();
moveIterator(it);  // iterator
moveIterator(cit); // const_iterator

虽然有从iteratorconst_iterator的转换,这将需要一个临时的引用来绑定,因为参数本身不是const_iterator的。因此,非常量左值引用是非起始引用。

iteratorconst_iterator甚至不需要是类类型。指针也是迭代器(实际上是优化构建中向量的迭代器类型(。考虑:

void foo(int const*& p) { }
void bar() {
  int i = 0;
  foo(&i); 
}

这会产生完全相同的错误。

你不能

这样做,因为它会让所有的地狱都松动。

请考虑以下代码:

#include <vector>
const std::vector<char> doNotChangeMe; // in ROM
void  breakMe(std::vector<char>::const_iterator& v) {
    v = doNotChangeMe.cbegin();   
}
int main() {
    std::vector<char> v;
    std::vector<char>::iterator iter = v.begin();
    breakMe(iter); // imagine this is allowed
    *iter=42; // what happens here?
}

这基本上与T **不可转换为const T **的原因相同。

const_iterator不是const iterator它们是不同的类型。

const std::vector::

iterator != std::vector::const_iterator