【问题标题】:Is there a standard wrapper class providing unified interface over iterator and reverse_iterator?是否有标准的包装类提供迭代器和反向迭代器的统一接口?
【发布时间】:2016-04-20 04:47:29
【问题描述】:

我需要实现一个类,该类能够按照参数指定的方向迭代容器到类的构造函数。假设该参数称为方向。

我的班级将有方法,有时会根据与此问题无关的其他条件增加迭代器。

所以我的想法是声明 X 类型的成员字段,它可以包含容器的 begin() 或 rbegin() 方法的返回值。该成员文件将在构造函数中初始化。

但问题是 X 的类型是什么。我想我可以实现通过虚函数提供通用接口的包装类。但也许标准库或Boost中有标准实现?

更新:我的设置与@Rabbid76 在他的回答中提供的代码非常匹配。我无法更改struct Iterator 的接口或删除此类。所以我的问题是是否可以用标准库中的东西替换IteratorBase/IteratorImpl

【问题讨论】:

  • 您应该发布一些代码,因为我不太了解您的设置。该类是否为容器类型模板化,然后使用指向容器的指针或其他东西构造它?我建议您将它传递给开始和结束迭代器,并且该类不知道这些迭代器是否是 reverse_iterators。
  • 你真正想做什么。听起来您已经设计了解决方案并需要帮助来实施它。如果您尝试描述您要解决的问题,可能会更好;我们有一个关于如何实施它的替代建议。
  • 请参阅en.cppreference.com/w/cpp/iterator/make_reverse_iterator,也许还有boost.org/doc/libs/1_49_0/libs/range/doc/html/range/reference/…。请注意,在进行转换时,您总是需要知道自己在处理什么(每个角落都潜伏着一个个错误)
  • @David:Loki Astari:Rabbid76 答案中的代码与我的设置相符。请参阅我的问题中的更新。
  • @LokiAstari:Rabbid76 答案中的代码与我的设置相符。请参阅我的问题中的更新。

标签: c++ boost stl


【解决方案1】:

那又怎样:

template < typename T >
struct IteratorBase
{
    using value_type = typename T::value_type;
    virtual value_type& val() = 0;
    virtual void next() = 0;
    virtual bool end( T &container ) = 0;
};

template < typename T, bool reverse = false >
struct IteratorTempl    : IteratorBase< T >
{
    IteratorTempl( T &container ) : m_it( container.begin() ) {}
    value_type& val() override { return *m_it; }
    void next() override { m_it ++; }
    bool end( T &container ) override { return m_it == container.end(); }
    typename T::iterator m_it;
};

template < typename T >
struct IteratorTempl< T, true > : IteratorBase< T >
{
    IteratorTempl( T &container ) : m_it( container.rbegin() ) {}
    value_type& val() override { return *m_it; }
    void next() override { m_it ++; }
    bool end( T &container ) override { return m_it == container.rend(); }
    typename T::reverse_iterator m_it;
};

template < typename T >
struct Iterator
{
    using value_type = typename T::value_type;
    Iterator( T &container,  bool reverse ) 
    {
        if ( reverse )
            m_it = new IteratorTempl<T, true>( container );
        else
            m_it = new IteratorTempl<T, false>( container );
    }
    ~Iterator(){ delete m_it; }
    value_type& val() { return m_it->val(); }
    void next() { m_it->next(); }
    bool end( T &container ) { return m_it->end( container ); }
    IteratorBase<T> *m_it;
};

#include <vector>

int main()
{
    std::vector<int> v{ 1,2,3,4,5 };

    for ( int i = 0; i < 2; i ++ )
    {
        Iterator< std::vector<int> > it( v, i!=0 );
        while ( !it.end(v) )
        {
            cout << it.val() << " ";
            it.next();
        }
    }
    return 0;
}

【讨论】:

  • 谢谢@Rabbid76。您的代码看起来与我脑海中的非常相似。因此,如果没有人会提出使用标准库而不是 IteratorBase/IteratorTempl 来实现相同效果的方法(但应该有 struct Iterator),我会将您的答案标记为最佳答案。
猜你喜欢
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
相关资源
最近更新 更多