By using boost perhaps or another way?
I want to create a function, to grab a subset of deque d
from (and including) index iStart to index 0, into a new deque, but also to set that those values in d
to 0. I thought about this:
std::deque<int> CreateSubset(std::deque<int>& d, int iStart )
{
int iSubsetSize = iStart+1;
std::deque<int> subset(iSubsetSize); // initialise a deque of a certain size.
std::deque<int>::iterator it = d.begin();
subset.assign (it, d.begin()+iStart+1);
for(;it != d.begin()+iStart+2; it++)
{
*it = 0;
}
return subset;
}
But it looks horrible to me - is there a nicer way?
As opposed to std::vector, the elements of a deque are not stored contiguously: typical implementations use a sequence of individually allocated fixed-size arrays, with additional bookkeeping, which means indexed access to deque must perform two pointer dereferences, compared to vector's indexed access which performs ...
In C++, the STL deque is a sequential container that provides the functionality of a double-ended queue data structure. In a regular queue, elements are added from the rear and removed from the front. However, in a deque, we can insert and remove elements from both the front and rear.
The deque has to keep track of how many elements it has and where those elements are. Adding an element changes that stored data, as does removing an element. Changing that data from two threads without synchronization is a data race, and produces undefined behavior. In short, you must synchronize those operations.
Here is how I'd do it in C++11. I believe the code is fairly elegant, and I don't think there is anything particularly inefficient about 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 forward iterators, moves the content between them to a newly created deque and sets it to 0 in the original.
The template as written makes two assumptions:
Both assumptions can be relaxed by introducing further template parameters or function arguments.
As you can see, I use std::make_move_iterator
to convert the input iterators to move iterators, thus causing the elements to be moved (rather than copied) to the destination. As long as these are int
, it won't really make a difference, though.
I use the std::fill
algorithm to set the original elements to 0.
This is how you could call this function template:
int main()
{
/* Creating d. */
std::deque<int> d
{ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
/* Extracting the first three elements into a new deque. */
auto d2 = extract(begin(d),begin(d) + 3);
/* Printing the results. */
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With