I would like to implement a copy of std::stack< boost::shared_ptr<T> >. Is there any way to do it without 3 copies? Here is the code:
template<typename T>
void copyStackContent(std::stack< boost::shared_ptr<T> > & dst,
std::stack< boost::shared_ptr<T> > const & src){
//// Copy stack to temporary stack so we can unroll it
std::stack< boost::shared_ptr<T> > tempStack(src);
/// Copy stack to array
std::vector< boost::shared_ptr<T> > tempArray;
while(!tempStack.empty()){
tempArray.push_back(tempStack.top());
tempStack.pop();
}
/// Clear destination stack
while(!dst.empty()){
dst.pop();
}
/// Create destination stack
for(std::vector< boost::shared_ptr<T> >::reverse_iterator it =
tempArray.rbegin(); it != tempArray.rend(); ++it){
dst.push( boost::shared_ptr<T>(new T(**it)) );
}
}
And a sample test:
void test(){
// filling stack source
std::stack< boost::shared_ptr<int> > intStack1;
intStack1.push( boost::shared_ptr<int>(new int(0)) );
intStack1.push( boost::shared_ptr<int>(new int(1)) );
intStack1.push( boost::shared_ptr<int>(new int(2)) );
intStack1.push( boost::shared_ptr<int>(new int(3)) );
intStack1.push( boost::shared_ptr<int>(new int(4)) );
// filling stack dest
std::stack< boost::shared_ptr<int> > intStack2;
copyStackContent(intStack2, intStack1);
assert(intStack1.size() == intStack2.size()); // same size
while(!intStack1.empty()){
assert(intStack1.top() != intStack2.top()); // != pointers
assert((*intStack1.top()) == (*intStack2.top())); // same content
intStack1.pop();
intStack2.pop();
}
}
If you want to maintain the ordering, you’re kind of stuck since stack doesn’t provide any iterators. If you don’t want to use a deque, you can at least make the code clearer (and more efficient under certain circumstances) by passing the source stack by value:
Though, I am suspicious of copying the values pointed to by shared_ptrs. Why even dynamically allocate if you’re going to be copying everything anyhow?