Clebo Sevic
Clebo Sevic

Reputation: 673

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

The syntax of moving std::unique_ptr<...>() somewhat eludes me, and i can't find a clear answer(to me at least), as to how i should move the unique_ptr around.

I have some heap-allocated Nodes and would like to create new Nodes, which have two already existing Nodes as children. Which in turn are supposed to be inserted into the vector.

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

I only get the error-meassage, that no matching function call was found.

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

Cann somebody help, or has an idea, where i can look for the correct syntax, and which move/copy-function i should use?

Upvotes: 1

Views: 110

Answers (2)

Caleth
Caleth

Reputation: 62719

It sounds like you want to merge two adjacent Nodes in your vector. You will need to do this in multiple steps

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

Upvotes: 2

eerorika
eerorika

Reputation: 238361

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

Take a look at declaration of at. The argument type is size_type (an integer type). You're trying to pass an iterator.

Upvotes: 3

Related Questions