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

SCF*_*nch 7 c++ constructor iterator stl concatenation

我有一个X类,我在这里提供了一个片段:

class X {
  public:
    template <typename Iter>
    X(Iter begin, Iter end) : mVec(begin, end) {}

  private:
    vector<Y> const mVec;
};
Run Code Online (Sandbox Code Playgroud)

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

template <typename Iter1, typename Iter2>
X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2) : mVec(???) { ??? }
Run Code Online (Sandbox Code Playgroud)

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

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

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

template <typename Iter1, typename Iter2>
X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2) 
  : mVec(concatenate(begin1, end1, begin2, end2)) { }
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*eas 9

好问题.我会尝试实现一个特定的迭代器包装器类型,将两个范围转换为单个范围.有些东西:

// compacted syntax for brevity...
template <typename T1, typename T2>
struct concat_iterator
{
public:
   typedef std::forward_iterator_tag iterator_category;
   typedef typename iterator_traits<T1>::value_type value_type;
   typedef *value_type pointer; 
   typedef &value_type reference;

   concat_iterator( T1 b1, T1 e1, T2 b2, T2 e2 ) 
      : seq1( b1 ), seq1end( e1 ), seq2( b2 ), seq2end( e2 );
   iterator& operator++() {
      if ( seq1 != seq1end ) ++seq1;
      else ++seq2;
      return this;
   }
   reference operator*() {
      if ( seq1 != seq1end ) return *seq1;
      else return *seq2;
   }
   pointer operator->() {
      if ( seq1 != seq1end ) return &(*seq1);
      else return &(*seq2);
   }
   bool operator==( concat_iterator const & rhs ) {
      return seq1==rhs.seq1 && seq1end==rhs.seq2 
          && seq2==rhs.seq2 && seq2end==rhs.seq2end;
   }
   bool operator!=( contact_iterator const & rhs ) {
      return !(*this == rhs);
   }
private:
   T1 seq1;
   T1 seq1end;
   T2 seq2;
   T2 seq2end;
};

template <typename T1, typename T2>
concat_iterator<T1,T2> concat_begin( T1 b1, T1 e1, T2 b2, T2 e2 )
{
   return concat_iterator<T1,T2>(b1,e1,b2,e2);
}
template <typename T1, typename T2>
concat_iterator<T1,T2> concat_end( T1 b1, T1 e1, T2 b2, T2 e2 )
{
   return concat_iterator<T1,T2>(e1,e1,e2,e2);
}
Run Code Online (Sandbox Code Playgroud)

现在您可以使用:

 class X {
 public:
    template <typename Iter, typename Iter2>
    X(Iter b1, Iter e1, Iter2 b2, Iter2 e2 ) 
      : mVec( concat_begin(b1,e1,b2,e2), concat_end(b1,e1,b2,e2) ) 
    {}

  private:
    vector<Y> const mVec;
};
Run Code Online (Sandbox Code Playgroud)

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

X x( concat_begin(b1,e1,b2,e2), concat_end(b1,e1,b2,e2) );
Run Code Online (Sandbox Code Playgroud)

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