1

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?

10
  • 2
    Please include a minimal reproducible example and the error message Commented Jan 24, 2019 at 14:34
  • 2
    From the semantical POV: Who should be the owner of that unique instance after the operation? Commented Jan 24, 2019 at 14:37
  • 2
    The std::vector's at member function takes an integer (technically a size_t) and not an iterator, so I think you can just use idx and idx + 1 directly in the calls to at. It's not about syntax, but about the types. I suspect that your error message says as much. Commented Jan 24, 2019 at 14:38
  • the owner should be the new Node @πάνταῥεῖ Commented Jan 24, 2019 at 14:42
  • 1
    @user463035818 did it, hope this is better Commented Jan 24, 2019 at 14:42

2 Answers 2

3
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.

Sign up to request clarification or add additional context in comments.

2 Comments

Weirdly enough this has worked for me before ... but ill look into it; thx
okay, found where it worked for me. wasn't at but ``` erease ```
2

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

3 Comments

+1 This will fix the problem of having empty (nullptr) nodes, which Clebo Sevic mentioned he'd rather not have in the vector.
How do i assign left and right to members of Node? = is a deleted function. Should i move again?
@CleboSevic The code in my answer moves when it needs to. In general member initializers are preferable to code in the body of the constructor.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.