提问者:小点点

C++如何为自己的迭代器类实现从迭代器到const_iterator的转换?


我正在编写一个STL like vector和一个迭代器类。 今天在写带const_iterator的擦除函数时,发现iterator到const_iterator之间没有对话,我试着找了一些信息,但还是不知道怎么做。 但STL向量不知怎的让它。 我的迭代器类:

template<typename VectorDataType>
class Iterator{
    public:
            using value_type = VectorDataType;
            using difference_type = int;
            using pointer = VectorDataType*;
            using reference = VectorDataType&;
            using iterator_category =  std::random_access_iterator_tag;
   public:
            explicit Iterator(VectorDataType* ptr = nullptr)
               : ptr(ptr){}
             Iterator(const Iterator<VectorDataType>& iter)
                : ptr(iter.ptr){}
            ~Iterator() {ptr = nullptr;}

             template<template<typename Y> class Alloc>
             operator typename Vector<VectorDataType, Alloc>::const_iterator (){
                   typename Vector<VectorDataType, Alloc>::const_iterator citer(*this);
                 return citer;
             }

            Iterator& operator=(VectorDataType* rhs) {this->ptr = rhs; return *this;}
            Iterator& operator=(const Iterator& rhs) {this->ptr = rhs.ptr; return *this;}


            operator bool() const{
                bool result = (this->ptr) ? true : false;
                return result;
            }

            bool operator==(const Iterator<VectorDataType>& iter) const{
                    return this->ptr == iter.ptr;
            }
            bool operator!=(const Iterator<VectorDataType>&iter) const{
                return this->ptr != iter.ptr;
            }

            bool operator<(const Iterator<VectorDataType>& iter)const {
                return this->ptr < iter.ptr;
            }
            bool operator>(const Iterator<VectorDataType>& iter)const {
                return this->ptr > iter.ptr;
            }

            bool operator<=(const Iterator<VectorDataType>& iter)const {
                return this->ptr <= iter.ptr;
            }
            bool operator>=(const Iterator<VectorDataType>& iter)const {
                return this->ptr >= iter.ptr;
            }

            Iterator<VectorDataType>& operator+=(const difference_type& offset){
                this->ptr +=  offset;
                return *this;
            }
            Iterator<VectorDataType>& operator-=(const difference_type& offset){
                this->ptr -= offset;
                return *this;
            }

            Iterator<VectorDataType>& operator++(){
                this->ptr++;
                return *this;
            }
            Iterator<VectorDataType>& operator--(){
                this->ptr--;
                return *this;
            }

            Iterator<VectorDataType> operator++(int){
                Iterator<VectorDataType> temp(*this);
                this->ptr++;
                return temp;
            }
            Iterator<VectorDataType> operator--(int){
                Iterator<VectorDataType> temp(*this);
                this->ptr--;
                return temp;
            }

            Iterator<VectorDataType> operator+(const difference_type&offset) const{
                VectorDataType* newPtr = ptr;
                newPtr += offset;
                return Iterator{newPtr};
            }
            Iterator<VectorDataType> operator-(const difference_type&offset) const{
                VectorDataType* newPtr = ptr;
                newPtr -= offset;
                return Iterator{newPtr};
            }

            difference_type operator-(const Iterator<VectorDataType>& iter)const{
                return std::distance(iter.ptr, this->ptr);
            }

            VectorDataType& operator*(){return  *ptr;}
            const VectorDataType& operator*()const{return  *ptr;}
            VectorDataType* operator->(){return ptr;}


            VectorDataType& operator[](int offset){
                return ptr[offset];
            }


   private:
        VectorDataType* ptr;
};

Main的代码:

auto list = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    Vector<int> vec(list);

    for(auto&i: vec)
       std::cout << i << "\t";

    auto iter = vec.begin();
    iter++;
    iter++;
    iter++;

    auto pos = vec.erase(iter);

    for(auto&i: vec)
       std::cout << i << "\t";

擦除定义:

iterator erase(const_iterator pos);

控制台日志:

g++ -c -pipe -g -std=gnu++1z -Wall -Wextra -fPIC  -I../MyVector -I. -I../../Qt/5.14.1/gcc_64/mkspecs/linux-g++ -o main.o ../MyVector/main.cpp
../MyVector/main.cpp: In function ‘int main()’:
../MyVector/main.cpp:49:30: error: no matching function for call to ‘Vector<int>::erase(Iterator<int>&)’
     auto pos = vec.erase(iter);
                              ^
In file included from ../MyVector/main.cpp:2:0:
../MyVector/MyVector.h:601:21: note: candidate: Vector<T, Allocator>::iterator Vector<T, Allocator>::erase(Vector<T, Allocator>::const_iterator) [with T = int; Allocator = std::allocator; Vector<T, Allocator>::iterator = Iterator<int>; Vector<T, Allocator>::const_iterator = Iterator<const int>]
            iterator erase(const_iterator pos){
                     ^~~~~
../MyVector/MyVector.h:601:21: note:   no known conversion for argument 1 from ‘Iterator<int>’ to ‘Vector<int>::const_iterator {aka Iterator<const int>}’
../MyVector/MyVector.h:618:21: note: candidate: Vector<T, Allocator>::iterator Vector<T, Allocator>::erase(Vector<T, Allocator>::const_iterator, Vector<T, Allocator>::const_iterator) [with T = int; Allocator = std::allocator; Vector<T, Allocator>::iterator = Iterator<int>; Vector<T, Allocator>::const_iterator = Iterator<const int>]

如果您想查看所有代码,这里有一个github链接:https://github.com/rrradicaledward/vector/blob/master/myvector.h


共2个答案

匿名用户

与所有用户定义转换的方式相同:

要么

  • 目标类型中的隐式转换构造函数或
  • 源类型中的隐式转换运算符

匿名用户

隐式转换运算符的问题在于,它将template-template参数alloc放在一个非推导的上下文中,即留给作用域运算符:

template <template <typename Y> class Alloc>
operator typename Vector<VectorDataType, Alloc>::const_iterator() {
//                           non-deduced ~~~~^
    typename Vector<VectorDataType, Alloc>::const_iterator citer(*this);
    return citer;
}

因此编译器无法应用此转换。 尝试将其更改为:

operator Iterator<const VectorDataType>() const {
    Iterator<const VectorDataType> citer(ptr);
    return citer;
}

还要注意,构造函数调用参数是一个指针,而不是迭代器(*this)本身。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++|何为|迭代|器|类|实|现从|迭代|器|const_iterator|转换)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?