Home > front end >  Using an unique_ptr as a member of a struct
Using an unique_ptr as a member of a struct

Time:06-22

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.

  • Related