【问题标题】:Custom container with custom iterator doesn't work when container defined as const当容器定义为 const 时,具有自定义迭代器的自定义容器不起作用
【发布时间】:2011-06-09 16:09:24
【问题描述】:


或多或少都在主题中。
当我有

func(my_cont& c)
{ c.begin() };

一切正常,但是

func(const my_cont& c)
{ c.begin() };

不起作用,编译器声称无法将其转换为 const my_cont<..>.... from my_cont<..>

容器和我的自定义迭代器有什么要求来处理这个问题?

【问题讨论】:

  • 你有一个const 版本的begin(),它返回一个与const 容器一起工作的迭代器吗?

标签: c++ templates iterator metaprogramming


【解决方案1】:

你需要添加一个 const begin(),像这样:

class my_cont
{
public:
    const_iterator begin() const;
};

您还必须定义 const_iterator 类型。

【讨论】:

    【解决方案2】:

    这正是 STL 为容器实现 cost_iterator 的原因。看看它是如何在 STL 中实现的,我不确定你是否能找到更好的解决方案。

    【讨论】:

      【解决方案3】:

      您只能在 const 对象上调用 const 成员函数(或在 volatile 对象上调用 volatile 成员函数)。 编译器告诉 iterator my_cont::begin() const 丢失了。

      【讨论】:

      • iterator my_cont::begin() const 不够用就像int* pr 不能在pr = &amp;r 中使用const int r 一样。需要的是 const_iterator 返回值(用于将来的操作),而不仅仅是 my_cont::begin() 方法本身的 const
      【解决方案4】:

      您的容器类应该有两个 begin() 和 end() 实现 - 一个返回迭代器,另一个返回 const_iterator:

            iterator begin ();
      const_iterator begin () const;
            iterator end ();
      const_iterator end () const;
      

      const_iterator 不能用于修改它指向的对象。

      【讨论】:

        【解决方案5】:

        这是一篇关于编写迭代器的好文章:
        http://www.aristeia.com/Papers/CUJ_June_2001.pdf

        正如大多数人所指出的,您需要一个返回 const_iterator 的 begin() 和 end() 的 const 版本。

        大多数人忘记的是迭代器应该能够隐式转换为 const_iterator。否则很难从非成本对象中获取 const 迭代器(没有很多讨厌的强制转换)。

         my_cont   data;
         for(my_cont::const_iterator loop = data.begin(); loop != data.end(); ++loop)
         {
             /* STUFF */
         }
        

        上面的注释:上面的调用实际上会调用非成本版本的 begin() 和 end()。但是它们被分配给一个 const_iterator。因此,您的迭代器必须可转换为 const_iterator 才能使上述代码正常工作(注意:没有从 const_iterator 到迭代器的隐式转换。这应该采用显式的 const_cast,因为它本质上是危险的)。

        class my_cont
        {
            public:
            class iterator { /* STUFF */ }
            class const_iterator
            {
                public: const_iterator(iterator const& rhs);
                /* STUFF */
            }
        
            iterator       begin();
            iterator       end();
        
            const_iterator begin() const;
            const_iterator end()   const;
            /* STUFF*/ 
        };
        

        【讨论】:

        • 这里有最深的答案。谢谢。来自 Meyers 的链接文章:“演员无法编译的原因是,对于这些容器类型,iteratorconst_iterator 是完全不同的类,彼此之间的关系几乎不比 string 和 @987654327 @。”
        猜你喜欢
        • 2013-02-17
        • 2021-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-08
        • 1970-01-01
        • 2015-09-06
        • 2020-04-21
        相关资源
        最近更新 更多