在构造时将C迭代器范围连接成const向量成员变量

前端之家收集整理的这篇文章主要介绍了在构造时将C迭代器范围连接成const向量成员变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个X类,我在这里提供了一个片段:
  1. class X {
  2. public:
  3. template <typename Iter>
  4. X(Iter begin,Iter end) : mVec(begin,end) {}
  5.  
  6. private:
  7. vector<Y> const mVec;
  8. };

我现在想要为这个类添加一个新的连接构造函数,例如:

  1. template <typename Iter1,typename Iter2>
  2. X(Iter1 begin1,Iter1 end1,Iter2 begin2,Iter2 end2) : mVec(???) { ??? }

这样的构造函数会将两个范围[begin1,end1]和[begin2,end2)连接到mVec中.挑战是

1)我想在mVec上保留const,因此在X的其他方法中它被认为是常量.

2)如果可能的话,我想避免不必要的副本.也就是说,一种解决方案是使用静态方法将非const临时构造到范围1,插入范围2并返回它,然后将连接构造函数定义为

  1. template <typename Iter1,Iter2 end2)
  2. : mVec(concatenate(begin1,end1,begin2,end2)) { }

但我相信,这至少会复制一次所有的价值.

解决方法

好问题.我会尝试实现一个特定的迭代器包装器类型,将两个范围转换为单个范围.有点像:
  1. // compacted Syntax for brevity...
  2. template <typename T1,typename T2>
  3. struct concat_iterator
  4. {
  5. public:
  6. typedef std::forward_iterator_tag iterator_category;
  7. typedef typename iterator_traits<T1>::value_type value_type;
  8. typedef *value_type pointer;
  9. typedef &value_type reference;
  10.  
  11. concat_iterator( T1 b1,T1 e1,T2 b2,T2 e2 )
  12. : seq1( b1 ),seq1end( e1 ),seq2( b2 ),seq2end( e2 );
  13. iterator& operator++() {
  14. if ( seq1 != seq1end ) ++seq1;
  15. else ++seq2;
  16. return this;
  17. }
  18. reference operator*() {
  19. if ( seq1 != seq1end ) return *seq1;
  20. else return *seq2;
  21. }
  22. pointer operator->() {
  23. if ( seq1 != seq1end ) return &(*seq1);
  24. else return &(*seq2);
  25. }
  26. bool operator==( concat_iterator const & rhs ) {
  27. return seq1==rhs.seq1 && seq1end==rhs.seq2
  28. && seq2==rhs.seq2 && seq2end==rhs.seq2end;
  29. }
  30. bool operator!=( contact_iterator const & rhs ) {
  31. return !(*this == rhs);
  32. }
  33. private:
  34. T1 seq1;
  35. T1 seq1end;
  36. T2 seq2;
  37. T2 seq2end;
  38. };
  39.  
  40. template <typename T1,typename T2>
  41. concat_iterator<T1,T2> concat_begin( T1 b1,T2 e2 )
  42. {
  43. return concat_iterator<T1,T2>(b1,e1,b2,e2);
  44. }
  45. template <typename T1,T2> concat_end( T1 b1,T2>(e1,e2,e2);
  46. }

现在你可以使用:

  1. class X {
  2. public:
  3. template <typename Iter,typename Iter2>
  4. X(Iter b1,Iter e1,Iter2 b2,Iter2 e2 )
  5. : mVec( concat_begin(b1,e2),concat_end(b1,e2) )
  6. {}
  7.  
  8. private:
  9. vector<Y> const mVec;
  10. };

或者(我刚刚想到它)你不需要重新声明你的构造函数.让调用者使用辅助函数

  1. X x( concat_begin(b1,e2) );

我没有检查过代码,只是在我的头顶输入它.它可以编译或它不能,它可以工作或不…但你可以把它作为一个起点.

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