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

时间:2019-02-07 10:55:46

标签: c++

这是代码。

#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引用的函数,为什么?

4 个答案:

答案 0 :(得分:3)

出于相同的原因,您无法使用%来呼叫f(std::string&)

在大多数实现中,

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

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

您可以做的是将std::vector<char>::iterator定义为模板:

moveIterator

答案 1 :(得分:1)

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

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

void foo(int const*& p) { }

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

哪个会产生完全相同的错误。

答案 2 :(得分:1)

您无法执行此操作,因为它会使所有地狱崩溃。

考虑以下代码:

#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 **的原因基本上相同。

答案 3 :(得分:0)

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

  

const std :: vector :: iterator!= std :: vector :: const_iterator