std::stack< 的深拷贝boost::shared_ptr; >

发布于 2024-09-30 10:28:01 字数 1884 浏览 0 评论 0 原文

我想实现 std::stack 的副本boost::shared_ptr; >。有没有办法不用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();
    }
}

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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

裸钻 2024-10-07 10:28:01

如果你想维持顺序,你就会陷入困境,因为堆栈不提供任何迭代器。如果你不想使用双端队列,至少可以让代码更清晰(并且更高效在某些情况下)通过按值传递源堆栈:

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指向的值持怀疑态度。如果您无论如何都要复制所有内容,为什么还要动态分配呢?

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:

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)) );
    }
}

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?

夜灵血窟げ 2024-10-07 10:28:01

在这种情况下,您最好的选择可能是只使用 deque 而不是 stack 并将 top 更改为 back等根据需要。然后您可以迭代并一次完成深复制。

或者找出为什么需要深层复制并尝试从源头上消除这种需求。

In this case your best bet is to probably just use a deque instead of a stack and change top to back etc as needed. Then you can iterate and do the deep copy in one pass.

Alternately figure out why you need the deep copy and try to remove that need at its source.

热血少△年 2024-10-07 10:28:01

不,您所拥有的与您将获得的一样高效。但是,如果您发现自己这样做,您可能应该简单地使用 std::vectorstd::deque 而不是堆栈。 std::stack 只是这些容器之一的包装器(通常是 std::deque)如果您使用这些容器中的任何一个,您可以通过使用来有效地反转顺序反向迭代器,如果您使用 std::deque,您甚至可以使用 push_front 在另一侧高效插入。

旁注:您可能还应该让 copyStackContent 返回一个新堆栈,而不是通过引用获取目标堆栈。它更具可读性,并且分配一个新堆栈并简单地释放旧堆栈比删除现有堆栈中的所有元素更便宜。

No, what you have is about as efficient as you're going to get. However, if you find yourself doing this, you should probably simply use a std::vector or std::deque instead of a stack. std::stack is merely a wrapper around one of these containers (usually std::deque) If you use either of these containers, you can effectively reverse the sequence by using reverse iterators, and if you're using a std::deque, you can even insert on the other side efficiently using push_front.

Side note: You should also probably have copyStackContent return a new stack instead of taking a destination stack by reference. It's more readable, and it can be cheaper to allocate a new stack and simply deallocate the old one than to erase all the elements from the existing stack.

温柔嚣张 2024-10-07 10:28:01

我的第一个答案很愚蠢,没有阅读整个问题,这是堆栈克隆操作的干净实现,汇集了上面讨论的想法,但仅使用堆栈......

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;
  }
};

My first answer was daft, didn't read the whole question, here is a clean implementation of a clone operation for stack bringing together the ideas discussed above, but using stacks only...

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;
  }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文