I have a class X, which I provide a snippet of here:
class X { public: template <typename Iter> X(Iter begin, Iter end) : mVec(begin, end) {} private: vector<Y> const mVec; };
I now want to add a new concatenating constructor to this class, something like:
template <typename Iter1, typename Iter2> X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2) : mVec(???) { ??? }
Such a constructor would catenate the two ranges [begin1, end1) and [begin2, end2) into mVec. The challenges are
1) I would like to preserve the const on mVec, so that it is considered constant throughout the other methods of X.
2) I would like to avoid unnecessary copies if at all possible. That is, one solution is to have a static method that constructs a non-const temporary to range 1, inserts range 2 and returns it, and then define the concatenating constructor to
template <typename Iter1, typename Iter2> X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2) : mVec(concatenate(begin1, end1, begin2, end2)) { }
but that copies all the values at least one extra time, I believe.
Nice problem. I would try to implement a particular iterator wrapper type that turns the two ranges into a single range. Something in the lines of:
Now you could use:
or (I have just thought of it) you don’t need to redeclare your constructor. Make your caller use the helper functions:
I have not checked the code, just typed it here off the top of my head. It could compile or it could not, it could work or not… but you can take this as a start point.