c – 如何展平嵌套容器的迭代器?

前端之家收集整理的这篇文章主要介绍了c – 如何展平嵌套容器的迭代器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是詹姆斯回答这个问题的一个(另一个)跟进: Flattening iterator

如何更改flattenig_iterator以使其递归工作?假设我有更多级别的嵌套容器,我不希望被限制在给定的嵌套深度.即flattening_iterator应该使用

  1. std::vector< std::vector < std::vector < int > > >@H_404_5@
  2. 以及

  3. std::vector< std::vector < std::vector < std::vector < int > > > >@H_404_5@ 
  4.  

    在我的实际代码中,我有一个对象数组,它们本身可能包含或不包含这样的数组.

  5.  

    编辑:

  6.  

    在使用不同方式迭代不同类型的嵌套容器之后,我学到了一些可能对其他人感兴趣的东西:

  7.  

    使用嵌套循环访问容器元素的速度比使用迭代器解决方案快56倍.

  8.  

    优点:

  9.  

    >元素可以是复杂的对象,例如(就像我的情况一样)包含容器的类.
    >执行速度更快

  10.  

    缺点:

  11.  

    >每个容器结构都需要一个新的循环实现
    >标准库算法不可用

  12.  

    其他利弊?

解决方法

好的,所以这不是一个完整的解决方案 – 但我没时间了.所以这当前实现的不是一个完整的迭代器,而是一个类似迭代器的类,它定义了类似这个接口的东西,并且需要C 11.我在g 4.7上测试过它:
  1. template<typename NestedContainerType,typename Terminator>
  2. class flatten_iterator
  3. {
  4. bool complete();
  5. void advance();
  6. Terminator& current();
  7. };@H_404_5@
  8. 其中NestedContainerType是嵌套的容器类型(令人惊讶),而Terminator是你想要从flatten中走出来的最里面的东西的类型.

  9. 下面的代码有效,但这肯定没有经过广泛测试.完全包装它(假设你对前进只是满意)不应该太多工作​​,特别是如果你使用boost::iterator_facade.

  10. #include <list>
  11. #include <deque>
  12. #include <vector>
  13. #include <iostream>
  14. template<typename ContainerType,typename Terminator>
  15. class flatten_iterator
  16. {
  17. public:
  18.     typedef flatten_iterator<typename ContainerType::value_type,Terminator> inner_it_type;
  19.     typedef typename inner_it_type::value_type value_type;
  20. public:
  21.     flatten_iterator() {}
  22.     flatten_iterator( ContainerType& container ) : m_it( container.begin() ),m_end( container.end() )
  23.     {
  24.         skipEmpties();
  25.     }
  26.     bool complete()
  27.     {
  28.         return m_it == m_end;
  29.     }
  30.     value_type& current()
  31.     {
  32.         return m_inner_it.current();
  33.     }
  34.     void advance()
  35.     {
  36.         if ( !m_inner_it.complete() )
  37.         {
  38.             m_inner_it.advance();
  39.         }
  40.         if ( m_inner_it.complete() )
  41.         {
  42.             ++m_it;
  43.             skipEmpties();
  44.         }
  45.     }
  46. private:
  47.     void skipEmpties()
  48.     {
  49.         while ( !complete() )
  50.         {
  51.             m_inner_it = inner_it_type(*m_it);
  52.             if ( !m_inner_it.complete() ) break;
  53.             ++m_it;
  54.         }
  55.     }
  56. private:
  57.     inner_it_type                    m_inner_it;
  58.     typename ContainerType::iterator m_it,m_end;
  59. };
  60. template<template<typename,typename ...> class ContainerType,typename Terminator,typename ... Args>
  61. class flatten_iterator<ContainerType<Terminator,Args...>,Terminator>
  62. {
  63. public:
  64.     typedef typename ContainerType<Terminator,Args...>::value_type value_type;
  65. public:
  66.     flatten_iterator() {}
  67.     flatten_iterator( ContainerType<Terminator,Args...>& container ) :
  68.         m_it( container.begin() ),m_end( container.end() )
  69.     {
  70.     }
  71.     bool complete()
  72.     {
  73.         return m_it == m_end;
  74.     }
  75.     value_type& current() { return *m_it; }
  76.     void advance() { ++m_it; }
  77. private:
  78.     typename ContainerType<Terminator,Args...>::iterator m_it,m_end;
  79. };@H_404_5@ 
  80.  

    通过以下测试用例,它可以满足您的期望:

  81.   
  82.  
    int main( int argc,char* argv[] )
  83. {   
  84.     typedef std::vector<int> n1_t;
  85.     typedef std::vector<std::deque<short> > n2_t;
  86.     typedef std::list<std::vector<std::vector<std::vector<double> > > > n4_t;
  87.     typedef std::vector<std::deque<std::vector<std::deque<std::vector<std::list<float> > > > > > n6_t;
  88.     n1_t n1 = { 1,2,3,4 };
  89.     n2_t n2 = { {},{ 1,2 },{3},{},{4},{} };
  90.     n4_t n4 = { { { {1.0},{2.0},{} },{ {},{ {3.0} } },{ { { 4.0 } } } };
  91.     n6_t n6 = { { { { { {1.0f},{2.0f},{ {3.0f} } },{ { { 4.0f } } } } } };
  92.     flatten_iterator<n1_t,int> i1( n1 );
  93.     while ( !i1.complete() )
  94.     {
  95.         std::cout << i1.current() << std::endl;
  96.         i1.advance();
  97.     }
  98.     flatten_iterator<n2_t,short> i2( n2 );
  99.     while ( !i2.complete() )
  100.     {
  101.         std::cout << i2.current() << std::endl;
  102.         i2.advance();
  103.     }
  104.     flatten_iterator<n4_t,double> i4( n4 );
  105.     while ( !i4.complete() )
  106.     {
  107.         std::cout << i4.current() << std::endl;
  108.         i4.advance();
  109.     }
  110.     flatten_iterator<n6_t,float> i6( n6 );
  111.     while ( !i6.complete() )
  112.     {
  113.         std::cout << i6.current() << std::endl;
  114.         i6.advance();
  115.     }
  116. }@H_404_5@ 
  117.  

    因此,为每种容器类型打印以下内容

  118.   
  119.  
    1
  120. 2
  121. 3
  122. 4@H_404_5@ 
  123.  

    请注意,它还没有使用集合,因为需要一些foo来处理set迭代器返回const引用这一事实.为读者练习…

猜你在找的C&C++相关文章