不錯的問題。我會嘗試實現一個特定的迭代器包裝類型,將兩個範圍變成一個範圍。東西的線路:
// 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));
我還沒有檢查過代碼,只是在這裏輸入了我的頭頂。它可以編譯或不能,它可以工作或不可以...但你可以把它作爲一個起點。
在我的情況下,構造實例後,vector成員變量不應該改變。使它成爲const可以幫助編譯器幫助我保證。 – SCFrench 2009-04-16 17:39:37
好吧,考慮到進行連接所需的代碼量,如果你保持const,那麼更有可能你的代碼會有bug。 – avakar 2009-04-16 17:53:53
SCFrench,是不是已經足夠安全了X :: mvec在X被構造後不會改變? – veefu 2009-04-16 18:51:02