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:
Implement a copy constructor for
Node
that does whatever would be a meaningful result for copy-constructing yourNode
.Re-engineer your code, in some way, that avoids copy-constructing
Node
s.
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