No, this is not so sad. Nearest <<20>.
And, of course, the algorithm you just wrote.
Depending on the type of iterator used (random or not), using this is more efficient (because only one check is needed for each iteration) than your algorithm:
std::copy_n(begin1, std::min(std::distance(begin1, end1), std::distance(begin2, end2)), begin2);
Another alternative is a proven output iterator, something along the lines of this (rough sketch, not verified code):
template<class Iter> class CheckedOutputIter { public: // exception used for breaking loops class Sentinel { } CheckedOutputIter() : begin(), end() { } CheckedOutputIter(Iter begin, Iter end) : begin(begin), end(end) { } CheckedOutputIter& operator++() { // increment pas end? if (begin == end) { throw Sentinel(); } ++begin; return *this; } CheckedOutputIter operator++(int) { // increment past end? if (begin == end) { throw Sentinel(); } CheckedOutputIter tmp(*this); ++begin; return tmp; } typename iterator_traits<Iter>::value_type operator*() { return *begin; } private: Iter begin, end; };
Using:
try { std::copy(begin1, end1, CheckedOutputIter(begin2, end2)); } catch(const CheckedOutputIter::Sentinel&) { }
This is about the same performance as your solution, but it is more widely used.
source share