So I have a struct like this:
struct node {
node_type type;
StaticTokensContainer token_sc;
std::unique_ptr<node> left; // here
std::unique_ptr<node> right; // and here
};
When I tried to write a recursive function to convert a node
to string for printing like this:
std::string node_to_string(node n) {
return "<other members converted to strings>" node_to_string(*(n.left));
}
It gives me: function "node::node(const node &)" (declared implicitly) cannot be referenced -- it is a deleted function
I don't understand why this error is showing up, I had no problem when I did (*n)
when I tried passing n as std::unique_ptr<node>
, so I don't see why doing *(n.left)
is not allowed.
CodePudding user response:
you pass node
by value, and you cannot set one std::unique_ptr
equal to another:
int main() {
std::unique_ptr<node> a = std::make_unique<node>();
std::unique_ptr<node> b = a; //Error C2280
}
because who is now the unique owner of the data?
To fix your error, simple take a const
reference in your function. This way, you pass the reference and that won't create copies:
std::string node_to_string(const node& n) {
return "<other members converted to strings>" node_to_string(*(n.left));
}
(you should also think about exiting this function, otherwise you will get either get a stack overflow or a dereferenced nullptr, whichever comes first. For example, add if (!n.left) return "";
)
CodePudding user response:
The compiler error basically tells you that the copy-constructor of struct node
is declared as implicitly deleted. To understand clearly what this means let's consider the following example.
struct node {
node_type type;
StaticTokensContainer token_sc;
node* left; // here
node* right; // and here
};
If you try the same thing with this struct declaration, you wil see that you get no error. So the problem must lie within the use of std::unique_ptr
.
Here we can see that there is written.
The implicitly-declared or defaulted copy constructor for class T is defined as deleted if any of the following conditions are true:
- T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors);
- ...
The std::unique_ptr
cannot be copied, as it is stated here
The class satisfies the requirements of MoveConstructible and MoveAssignable, but of neither CopyConstructible nor CopyAssignable.