c++ - 为什么在此代码中隐式转换为常量迭代器会失败?

标签 c++ iterator doubly-linked-list const-iterator

这与我之前的问题有关here .

这是该线程的摘要:我正在尝试实现一个名为 my_list 的双向链表类。在 C++ 中,包括迭代器,我希望将迭代器自动隐式转换为 const_iterator。

我最初的想法是有类似的东西

template<class T>
class my_list_iterator<T>
{
    node<T> pos_;
    /* code */
    operator my_list_iterator<const T>(){return my_list_iterator<const T>(pos_);}
};

然后在my_list里面定义 iterator作为my_list_iterator<T>const_iterator作为my_list_iterator<const T> .

但是,正如 Miled Budneck 在上一个线程中指出的那样,这将不起作用,因为指向 node<T> 的指针无法转换为指向 node<const T> 的指针.他建议我将 const 迭代器重新实现为指向 const 节点的指针。

虽然这行得通,但环顾四周,我还发现了另一种定义迭代器类的可能方法:

template<class T, class Pointer, class Reference>
class my_list_iterator {
    node<T>* pos_;
    /* code */
    operator my_list_iterator<T,const Pointer,const Reference>() {return my_list_iterator<T,const Pointer,const Reference>(pos_);}
};

然后我可以定义my_list<T>::iterator作为my_list_iterator<T,T*,T&>my_list<T>::const_iterator作为my_list_iterator<T,const T*,const T&> .我以为最后一行会处理隐式转换问题,但它似乎根本没有被使用。

作为引用,这里是完整的代码:

template<class T> class node {
    node(const T& t = T()):data(t),next(0),prev(0) {}
    T data;
    node* next;
    node* prev;

    friend class my_list<T>;
    template<class U,class Pointer,class Reference> friend class my_list_iterator;
};

template<class T,class Pointer,class Reference> class my_list_iterator {
    public:
            // increment and decrement operators
            my_list_iterator operator++();
            my_list_iterator operator++(int);
            my_list_iterator operator--();
            my_list_iterator operator--(int);

            // bool comparison iterators
            bool operator==(const my_list_iterator& other) const {return pos_==other.pos_;}
            bool operator!=(const my_list_iterator& other) const {return pos_!=other.pos_;}

            // member access
            Reference operator*() const {return pos_->data;}
            Pointer operator->() const {return &(pos_->data);}

            // conversion to constant
            operator my_list_iterator<T,const Pointer,const Reference>() {return pos_;}

    private:
            node<T>* pos_;
            explicit my_list_iterator(node<T>* p=0):pos_(p) {}
            friend class my_list<T>;
};

最后的错误信息

note:   no known conversion for argument 1 from ‘my_list<int>::iterator’ {aka ‘my_list_iterator<int, int*, int&>’} to ‘const my_list_iterator<int, const int*, const int&>&’

那么为什么这段代码不起作用?我是否可以做一些小的修改来让它工作,或者这个设计是不可能实现的?

最佳答案

给定Pointer = T* , const PointerT* const , 不是 const T* .类型替换不像宏展开。 const Pointer添加一个顶级 constPointer 表示的类型.同样,const ReferenceT& const (它会自动调整为 T&,因为引用中的顶级 cv 限定符被忽略)而不是 const T& . (有关 T* constconst T* 之间的区别,请参阅 What is the difference between const int*, const int * const, and int const *?。)

你需要使用类似 const std::remove_pointer<Pointer>* 的东西为了这个工作。

关于c++ - 为什么在此代码中隐式转换为常量迭代器会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57719751/

相关文章:

c++ - 如何使用1d索引迭代2d vector

c++ - 用于 GUI 的 Qt Designer C++ 或 QML

c++ - 有效地从 std::list 中删除最后一个元素

c++ - 使用 CMake 构建 PubNub C++

java - 遍历字符数组列表

rust - 如何在 Rust 中正确使用 `peek()`?

c++ - 如何在 C++ 中解析 XML 字符串中的数据?

Java:当我插入带有头虚拟节点的循环双向链表时,我的虚拟节点会被打乱。为什么?

c - 按字母顺序排序双向链表

c++ - 我有一个适用于整数的程序,但我需要让它也适用于小数