[英]Deep copy of std::stack< boost::shared_ptr<T> >
我想实现std::stack< boost::shared_ptr<T> >
的副本。 没有3份副本有没有办法做到这一点? 这是代码:
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)) );
}
}
并进行了样本测试:
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();
}
}
在这种情况下你最好的选择是可能只是使用deque
代替的stack
,并更改top
到back
的需要等。 然后,您可以在一次传递中迭代并执行深层复制。
或者,找出为什么需要深层复制并尝试从源头删除该需求。
如果你想维护这个顺序,你就会陷入困境,因为stack不提供任何迭代器。 如果您不想使用双端队列,则至少可以通过按值传递源堆栈来使代码更清晰( 在某些情况下更有效):
template<typename T>
void copyStackContent(std::stack< boost::shared_ptr<T> > & dst,
std::stack< boost::shared_ptr<T> > 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)) );
}
}
虽然,我怀疑复制shared_ptrs指向的值。 如果你要复制一切,为什么甚至动态分配呢?
不,你所拥有的就像你将获得的那样高效。 但是,如果你发现自己这样做,你应该简单地使用std::vector
或std::deque
而不是堆栈。 std::stack
只是这些容器之一的包装器(通常是std::deque
)如果你使用这些容器中的任何一个,你可以通过使用反向迭代器有效地反转序列,如果你使用的是std::deque
,您甚至可以使用push_front
高效地插入另一端。
旁注:您还应该让copyStackContent
返回一个新堆栈,而不是通过引用获取目标堆栈。 它更具可读性,分配新堆栈并简单地解除分配旧堆栈比清除现有堆栈中的所有元素要便宜得多。
我的第一个答案是daft,没有读完整个问题,这里是一个克隆操作的干净实现,堆栈汇集了上面讨论的想法,但只使用堆栈...
template <typename T, typename _CT = boost::shared_ptr<T>, typename _ST = std::stack<_CT> >
struct cloner
{
inline _CT copy(_CT t)
{
return _CT(new T(*t));
}
_ST operator()(_ST src)
{
_ST temp;
while(!src.empty())
{
temp.push(copy(src.top()));
src.pop();
}
while(!temp.empty())
{
src.push(temp.top());
temp.pop();
}
return src;
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.