Std :: unique_ptr compiler error: members of a derived class cannot access private members of a base class

I get C2248 Compiler Error when I try to compile the following code:

#include <list> #include <memory> using namespace std; class data { public: static data parse() { data d; data::parse(d); return d; } list<std::unique_ptr<data>> l; private: static void parse(data& node) { } }; int main() { return 0; } 

Why? How can i fix this?

Note. I have no problem using std::shared_ptr instead of std::unique_ptr .

+6
source share
3 answers

You need to provide move operations for your type:

 data(data&& other) : l(std::move(other.l)) { } data& operator=(data&& other) { l = std::move(other.l); return *this; } 

And, since you add the constructor declared by the user, you will also need the default constructor declared by the user:

 data() { } 

I understand that your code is correct as it is, in accordance with the final C ++ 11 language standard. Visual C ++ does not fully implement the final specification when move operations are implicitly generated (as in Visual C ++ 2012 RC). The specification, when implicit move operations are generated, has changed dramatically several times during the standardization process.

If you have a class type C that has any data member that is movable but not copyable, Visual C ++ will not generate an implicit move constructor or move an assignment operator, and the implicit copy constructor and copy assignment operator will be suppressed data item to move only. In other words, if you want aggregate types to be move-only, you must provide the move operations for the aggregation class yourself.

(At least this is my understanding from experimenting with the compiler.)

+10
source

First of all, VC ++ does not automatically generate the ctor movement and does not transfer the assignment operator, which means that you need to define them yourself.

Then, when you return the local variables, the compiler first tries to move them before actually going the normal way of copying them. However, for this he needs the ctor movement. Since it does not have this, it tries a regular copy and through the generated copy, ctor automatically calls the copy constructor std::list , which in turn tries to call the ctor copy of its element type, which is private in the std::unique_ptr case.

You need to either determine the appropriate ctor move, or a ctor copy that does not call std::unique_ptr copy ctor (i.e. make a deep copy of the content).

+5
source

Short answer: (for C ++ 11) Elements in list must be copyable or moveable. A unique_ptr cannot be copied by design, but it can be moved while the monitored type is also moved.

Your data type is not moving because you did not implement the semantics of the move, and the compiler did not do this for you.

Implement move semantics, and you can use unique_ptr in list :

 data(ddata&&) {}; 

According to the standard, the compiler will generate a move constructor for your class. However, VS10 does not support this - perhaps this is the problem you are working with.

For more information, see my post in CR: Canonical Implementation of Movement Semantics

+2
source

Source: https://habr.com/ru/post/919622/


All Articles