我有一个 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 上的常量,以便它在 X 的其他方法中被认为是常量。
2) 如果可能的话,我想避免不必要的拷贝。也就是说,一种解决方案是使用一个静态方法构造一个非常量临时值到范围 1,插入范围 2 并返回它,然后将连接构造函数定义为
template <typename Iter1, typename Iter2>
X(Iter1 begin1, Iter1 end1, Iter2 begin2, 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, 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);
}
现在你可以使用:
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;
};
或者(我刚刚想到)您不需要重新声明您的构造函数。让你的调用者使用辅助函数:
X x( concat_begin(b1,e1,b2,e2), concat_end(b1,e1,b2,e2) );
我没有检查代码,只是在我的脑海中输入了它。它可以编译也可以不编译,可以工作也可以不工作……但您可以以此为起点。
关于c++ - 在构造时将 C++ 迭代器范围连接到一个 const vector 成员变量中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/757153/