如何为非const类调用const_iterator?

Zep*_*yer 4 c++ templates iterator const

我读了一些与此问题相关的其他线程,但没有为我的问题提供解决方案.我希望你们能给我一些想法或建议.

我正在尝试实现这个名为的类Map.它应该包含2个迭代器 - iteratorconst_iterator.

我实现了它们 - iterator继承自const_iterator,在Map类中我有以下功能:

iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
Run Code Online (Sandbox Code Playgroud)

我们获得了一个示例文件,以了解实现所需的内容.在那里,有以下代码:

Map<std::string,int> msi;
Run Code Online (Sandbox Code Playgroud)

...

// print map
for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) {
// more stuff here
}
Run Code Online (Sandbox Code Playgroud)

因为msi是一个非常量的Map实例,msi.begin()调用iterator begin()和不调用const_iterator begin() const,导致意外的行为.

假设示例文件没问题,我该怎么做才能msi.begin()调用正确的const_iterator函数?(考虑到它,迭代器,是类型const_iterator).

编辑:关于自动转换的讨论,我决定添加我的迭代器类,请指出我的错误.

class Map {

    //...

    public:

        class const_iterator {

        private:

            Node* currNode;

        public:


            const_iterator(Node* cur_node = NULL) : currNode(cur_node) {}

            const_iterator& operator++() {
                currNode = currNode->next;
                return *this;
            }

            const_iterator operator++(int) {
                const_iterator old = *this;
                ++(*this);
                return old;
            }

            bool operator!=(const_iterator const& curr) {

                return !(*this == curr);
            }

            string operator*() {
                // this might cause memory leak
                string toString(this->currNode->key);
                std::stringstream s;
                int tmp = this->currNode->value;
                s << tmp;
                string secondString(s.str());
                toString = toString + ":" + secondString;
                return toString;
            }

            bool operator==(const_iterator const& curr) {
                return this->currNode == curr.currNode;
            }


            void operator=(const_iterator target) {
                this = target;
            }

            //void operator=(Node* target) {
            //    this->currNode = target;
            //}
        };

        class iterator : public const_iterator {

        private:

            Node* currNode;

        public:

            iterator(Node* cur_node = NULL) : currNode(cur_node) {}

            iterator& operator++() {
                currNode = currNode->next;
                return *this;
            }

            iterator operator++(int) {
                iterator old = *this;
                ++(*this);
                return old;
            }

            bool operator==(iterator const& curr) {
                return *this == curr;
            }

            bool operator!=(iterator const& curr) {

                return !(*this == curr);
            }

            string operator*() {
                // this might cause memory leak
                string toString(this->currNode->key);
                std::stringstream s;
                int tmp = this->currNode->value;
                s << tmp;
                string secondString(s.str());
                toString = toString + ":" + secondString;
                return toString;
            }

            void operator=(iterator target) {
                this = target;
            }

        };

        //..
}
Run Code Online (Sandbox Code Playgroud)

Kon*_*lph 7

C++ 11标准容器添加cbegincend用于此目的.由于缺乏这一点,您显然可以始终将对象const&显式转换为获取const对象的视图.

但更根本的是,你没有理由iterator不支持自动转换const_iterator.像这样,您根本不需要更改客户端代码.事实上,你的代码应该已经支持,如果这一点,因为你已经说过了,iterator从继承const_iterator.

但是,您发布的代码包含多个错误.首先,operator=是错误的,你应该收到错误.更正后的版本是:

void operator=(const_iterator target) {
    currNode = target.currNode;
}
Run Code Online (Sandbox Code Playgroud)

更重要的是,你的继承毫无意义.的确,你继承iteratorconst_iterator,但你的代码假装这从来没有发生过- iterator完全重新实现它的父类和不涉及以任何方式.

iterator 应该看起来像这样:

class iterator : public const_iterator {
public:
    iterator(Node* cur_node = NULL) : const_iterator(cur_node) {}
};
Run Code Online (Sandbox Code Playgroud)

这当然需要在currNode声明protected中声明const_iterator.那个类也完全没用(但是你的目前也是如此)因为它没有为const_iterator类添加任何功能.您需要实现一个operator*允许修改其值的方法.您当前的代码从根本上不允许这样做,因为它返回一个新创建的字符串,而不是(类似于)对地图值的引用.

此外,还不清楚const_iterator该类如何首先获得非const Node指针.这应该是不可能的:毕竟,它从a获取指针const Map.