代码之家  ›  专栏  ›  技术社区  ›  Searene

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

c++
  •  1
  • Searene  · 技术社区  · 6 年前

    这是密码。

    #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 回复  |  直到 6 年前
        1
  •  3
  •   YSC    6 年前

    因为同样的原因你不能打电话 f(std::string&) 用一个 std::vector<char> .

    在大多数实现中,

    • 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
    
        2
  •  1
  •   StoryTeller - Unslander Monica    6 年前

    当有一个转换自 iterator const_iterator ,因为参数不是 常数迭代器 本身。因此,非常量左值引用是非起始引用。

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

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

    产生完全相同的误差。

        3
  •  1
  •   n. m. could be an AI    6 年前

    你不能这样做,因为这会让所有的地狱都破灭。

    考虑此代码:

    #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 ** .

        4
  •  0
  •   user32434999    6 年前

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

    const std::vector::迭代器!=std::vector::const_迭代器