我有一个X类,我在这里提供了一个片段:
class X { public: template <typename Iter> X(Iter begin,Iter end) : mVec(begin,end) {} private: vector<Y> const mVec; };
template <typename Iter1,typename Iter2> X(Iter1 begin1,Iter1 end1,Iter2 begin2,Iter2 end2) : mVec(???) { ??? }
这样的构造函数会将两个范围[begin1,end1]和[begin2,end2)连接到mVec中.挑战是
1)我想在mVec上保留const,因此在X的其他方法中它被认为是常量.
2)如果可能的话,我想避免不必要的副本.也就是说,一种解决方案是使用静态方法将非const临时构造到范围1,插入范围2并返回它,然后将连接构造函数定义为
template <typename Iter1,Iter2 end2) : mVec(concatenate(begin1,end1,begin2,end2)) { }
但我相信,这至少会复制一次所有的价值.
解决方法
好问题.我会尝试实现一个特定的迭代器包装器类型,将两个范围转换为单个范围.有点像:
// 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,T2 e2 ) { return concat_iterator<T1,T2>(b1,e1,b2,e2); } template <typename T1,T2> concat_end( T1 b1,T2>(e1,e2,e2); }
现在你可以使用:
class X { public: template <typename Iter,typename Iter2> X(Iter b1,Iter e1,Iter2 b2,Iter2 e2 ) : mVec( concat_begin(b1,e2),concat_end(b1,e2) ) {} private: vector<Y> const mVec; };
或者(我刚刚想到它)你不需要重新声明你的构造函数.让调用者使用辅助函数:
X x( concat_begin(b1,e2) );
我没有检查过代码,只是在我的头顶输入它.它可以编译或它不能,它可以工作或不…但你可以把它作为一个起点.