从 Vector 中删除 unique_ptr´s 并将它们用作新 Struct 的参数

Removing unique_ptr´s from a Vector and using them as parameters for new Struct

移动 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> > > > > >)’

有人可以帮忙,或者有想法,我可以在哪里寻找正确的语法,我应该使用哪个 move/copy-function?

vec.at(vec.begin() + idx)

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

听起来您想合并向量中的两个相邻 Node。您将需要分多个步骤执行此操作

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