This is how I would do it in C ++ 11. I think the code is pretty neat and I donโt think there is anything particularly inefficient in it:
#include <iostream> #include <deque> #include <iterator> #include <algorithm> template <typename ForwardIt> std::deque<int> extract(ForwardIt from, ForwardIt to) { using std::make_move_iterator; std::deque<int> d2(make_move_iterator(from), make_move_iterator(to)); std::fill(from,to,0); return d2; }
The extract() function template takes two iterators forward, moves the contents between them to the newly created deque, and sets it to 0 in the original.
In the written template, two assumptions are made:
- Although the source iterators may refer to something, the destination is always deque;
- The default value for resetting the source elements is 0.
Both assumptions can be mitigated by introducing additional template parameters or function arguments.
As you can see, I use std::make_move_iterator to convert input iterators to move iterators, which causes the elements to move (rather than copy) to the destination. As long as they are int , it really doesn't matter.
I use the std::fill algorithm to set the source elements to 0.
Here is how you could call this function template:
int main() { std::deque<int> d { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; auto d2 = extract(begin(d),begin(d) + 3); std::cout << "d:\n"; for (const auto &elem : d) std::cout << elem << ','; std::cout << "\n\nd2:\n"; for (const auto &elem : d2) std::cout << elem << ','; std::cout << std::endl; return 0; }