Home > Software design >  error: call to implicitly-deleted copy constructor of <T> unique_ptr
error: call to implicitly-deleted copy constructor of <T> unique_ptr

Time:10-24

I'm trying to create a unique pointer to a <Node> type variable:

#include <memory>

struct Node
{
    int val;
    std::unique_ptr<Node> next;

    Node(int value, std::unique_ptr<Node> nextNode) : val(value), next(std::move(nextNode)){};
}

int main()
{
    Node headNode = Node(1, nullptr);
    std::unique_ptr<Node> head = std::make_unique<Node>(headNode);

    return 0;
}

And when I'm compiling this code I'm getting the following error:

error: call to implicitly-deleted copy constructor of 'Node'
    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
                               ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in instantiation of function template specialization 'std::make_unique<Node, Node &>' requested here
    std::unique_ptr<Node> head = std::make_unique<Node>(headNode);
                                      ^
note: copy constructor of 'Node' is implicitly deleted because field 'next' has a deleted copy constructor
    std::unique_ptr<Node> next;
                          ^
note: copy constructor is implicitly deleted because 'unique_ptr<Node>' has a user-declared move constructor
  unique_ptr(unique_ptr&& __u) _NOEXCEPT

CodePudding user response:

std::make_unique<Node>(headNode);

This constructs a unique Node by attempting to copy-construct it from another Node.

std::unique_ptr is not copyable, by definition (that would be due to the "unique" part of "unique_ptr"). This means that any class that contains a std::unique_ptr is not copyable by default, and its default copy-constructor is deleted.

This is the reason for your compilation error. You would get the same compilation error without involving std::unique_ptr:

Node node2{headNode};

This results in the same compilation error. You have two options:

  1. Implement a copy constructor for Node that does whatever would be a meaningful result for copy-constructing your Node.

  2. Re-engineer your code, in some way, that avoids copy-constructing Nodes.

If your described goal is "a unique pointer to a type variable", then this does not require copy-constructing it, merely:

std::unique_ptr<Node> head = std::make_unique<Node>(1, nullptr);

CodePudding user response:

Should work


#include <memory>

struct Node
{
    using NodePtr = std::unique_ptr<Node>;

    int val;
    NodePtr next;

    Node(int value, NodePtr&& nextNode)
        : val(value)
        , next(std::move(nextNode))
    {
    }
};

int main()
{
    auto headNode = std::make_unique<Node>(1, nullptr);
    auto head = std::make_unique<Node>(0, std::move(headNode));

    return 0;
}

At line std::unique_ptr<Node> head = std::make_unique<Node>(headNode); make_unique calls ctor for Node and unique_ptr (making 1 allocation)

So, args passed into std::make_unique() are used to build T instance. Your Node has ctor, that takes 2 params, not 1.

std::unqiue_ptr hasn't copy ctor and copy operator=() (e.g auto newPtr = oldPtr), so every function that deals with std::unique_ptr in argument list, should take this smart pointer by rvalue-reference - std::unique_ptr<T>&&. And final call must look like this f(std::move(ptr)), where f - function, or in our case - ctor of Node

If you are not familiar with T - consider T as AnyType

  • Related