【问题标题】:C++ iterator and const_iterator problem for own container class自己的容器类的 C++ 迭代器和 const_iterator 问题
【发布时间】:2011-02-20 02:55:37
【问题描述】:

我正在编写一个自己的容器类,但遇到了一个我无法理解的问题。这是显示问题的简单示例。

它由一个容器类和两个测试类组成:一个使用 std:vector 的测试类可以很好地编译,第二个测试类尝试以完全相同的方式使用我自己的容器类,但编译失败。

#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

template <typename T>
class MyContainer
{
public:
  
  class iterator
  {
  public:
    typedef iterator self_type;
    inline iterator() { }
  };

  class const_iterator
  {
  public:
    typedef const_iterator self_type;
    inline const_iterator() { }
  };
  
  iterator begin() {
    return iterator();
  }

  const_iterator begin() const {
    return const_iterator();
  }
};

// This one compiles ok, using std::vector
class TestClassVector
{
public:
  void test() {
    vector<int>::const_iterator I=myc.begin();
  }

private:
  vector<int> myc;
};

// this one fails to compile. Why?
class TestClassMyContainer
{
public:
  void test(){
    MyContainer<int>::const_iterator I=myc.begin();
  }

private:
  MyContainer<int> myc;
};


int main(int argc, char ** argv)
{
  return 0;
}

gcc 告诉我:

test2.C:在成员函数'void TestClassMyContainer::test()'中:

test2.C:51:错误:请求从“MyContainer::iterator”转换为非标量类型“MyContainer::const_iterator”

我不确定编译器在哪里以及为什么要将迭代器转换为我自己的类的 const_iterator,而不是 STL 向量类。我做错了什么?

【问题讨论】:

    标签: c++ stl containers const-iterator


    【解决方案1】:

    当您调用 begin() 时,编译器默认创建对非 const begin() 的调用。由于 myc 不是 const,它无法知道您的意思是使用 const begin() 而不是非 const begin()

    STL 迭代器包含一个强制转换运算符,它允许将iterator 静默转换为const_iterator。如果你想让它工作,你需要像这样添加一个:

    class iterator
    {
    public:
        typedef iterator self_type;
        inline iterator() { }
    
        operator const_iterator() { return const_iterator(); }
    };
    

    或允许const_iteratoriterator 构造,如下所示:

    class const_iterator
    {
    public:
        typedef const_iterator self_type;
    
        const_iterator(iterator& ) {}
        inline const_iterator() { }
    };
    

    【讨论】:

    • 非常感谢。现在我只需要看看我是否将 const_iterator 声明为 iterator 的朋友......还是将访问器函数写入私有迭代器成员,但这应该是可行的。
    【解决方案2】:

    您应该看看 Boost.Iterators 库,尤其是 iterator_facadeiterator_adaptor 部分。它们包含“从头开始”构建的迭代器。

    它将向您展示如何在没有太多重复的情况下编写迭代器,因为除了 const 限定符本身之外,const 和非 const 版本的代码大部分时间都差不多。使用模板可以编写一次,然后声明两种不同的类型,这就是库文档说明的内容。

    【讨论】:

      【解决方案3】:

      在容器中iterator 类型必须可转换为const_iterator。在使用非可变(const)迭代器迭代可变容器的情况下,这是必需的,因为这非常有意义。在您的情况下,myc 是可变的(非 const),但您在其上创建了一个 const 迭代器。

      【讨论】:

      • 反之亦然 - iterator 必须可转换为 const_iterator
      猜你喜欢
      • 2021-03-19
      • 2011-12-07
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-12
      • 1970-01-01
      • 2018-12-13
      相关资源
      最近更新 更多