【问题标题】:Removing unique_ptr´s from a Vector and using them as parameters for new Struct从 Vector 中删除 unique_ptr´s 并将它们用作新 Struct 的参数
【发布时间】:2026-02-23 11:05:02
【问题描述】:

移动std::unique_ptr<...>() 的语法让我有些摸不着头脑,我找不到明确的答案(至少对我来说),关于我应该如何移动 unique_ptr。

我有一些堆分配节点并想创建新节点,其中有两个已经存在的节点作为子节点。依次应该将其插入向量中。

#include <memory>
#include <vector> 

template <typename T>
struct Node{
    std::unique_ptr<Node<T>> left, right;
    Node(std::unique_ptr<Node<T>> left, std::unique_ptr<Node<T>> right){
          this->left = left;
          this->right = right;
    }
}

template <typename T>
void foo(){
    std::vector<std::unique_ptr<Node<T>>> vec;
    //...
    vec.insert(vec.begin() + idx, std::unique_ptr<Node<T>>(new Node<T>(vec.at(vec.begin() + idx), vec.at(vec.begin() + idx + 1))));
}

我只收到错误消息,没有找到匹配的函数调用。

expression.hpp:69:58: error: no matching function for call to ‘std::vector<std::unique_ptr<Node<int>, std::default_delete<Node<int> > >, std::allocator<std::unique_ptr<Node<int>, std::default_delete<Node<int> > > > >::at(__gnu_cxx::__normal_iterator<std::unique_ptr<Node<int>, std::default_delete<Node<int> > >*, std::vector<std::unique_ptr<Node<int>, std::default_delete<Node<int> > >, std::allocator<std::unique_ptr<Node<int>, std::default_delete<Node<int> > > > > >)’

谁能帮忙,或者有一个想法,我可以在哪里寻找正确的语法,我应该使用哪个移动/复制功能?

【问题讨论】:

  • 请附上minimal reproducible example 和错误信息
  • 从语义 POV 来看:手术后谁应该是那个唯一实例的所有者?
  • std::vectorat 成员函数采用整数(技术上是 size_t)而不是迭代器,所以我认为您可以直接在调用中使用 idx 和 idx + 1到at。这不是关于语法,而是关于类型。我怀疑你的错误信息说明了很多。
  • 所有者应该是新节点@πάνταῥεῖ
  • @user463035818 做到了,希望这样会更好

标签: c++ vector unique-ptr


【解决方案1】:
vec.at(vec.begin() + idx)

查看at 的声明。参数类型是size_type(整数类型)。您正在尝试传递一个迭代器。

【讨论】:

  • 奇怪的是,这以前对我有用……但我不仔细研究它;谢谢
  • 好的,找到对我有用的地方。不是at 而是``` 删除```
【解决方案2】:

听起来您想在向量中合并两个相邻的Nodes。您需要分多个步骤完成此操作

template <typename T>
struct Node{
    std::unique_ptr<Node<T>> left, right;
    Node(std::unique_ptr<Node<T>> left, std::unique_ptr<Node<T>> right)
        : left(std::move(left)),
        right(std::move(right))
    {}
}
template <typename T>
void foo(){
    std::vector<std::unique_ptr<Node<T>>> vec;
    //...

    // Identify first element
    auto first = vec.begin() + idx; 
    // and second element
    auto second = first + 1; 

    // make the merged node
    auto merged = std::make_unique<Node<T>>(std::move(*first), std::move(*second));

    // remove the now empty Node pointers - note that this relies on the adjacency of first and second
    auto pos = vec.erase(first, first + 2);

    // add the new node to the correct place
    vec.emplace(pos, std::move(merged));
}

【讨论】:

  • +1 这将解决空(nullptr)节点的问题,Clebo Sevic 提到他宁愿在向量中没有。
  • 如何将leftright 分配给Node 成员? = 是一个被删除的函数。我应该再搬家吗?
  • @CleboSevic 我的答案中的代码会在需要时移动。一般来说,成员初始化器比在构造函数的主体中编码更可取。
最近更新 更多