Reputation: 2655
I have a tree class that has move constructors and move assignment operators declared and defined.
Why would the compiler feel the need to synthesize a copy constructor and then complain that std::unique_ptr
has private members?
This seems counterproductive. Should the compiler not be aware that hidden copy and assignment with no body or simply not defined are to prevent trying to copy a std::unique_ptr
?
And, why does declaring and defining copy constructors and assignment operators with an empty body make the compiler happy?
Will this be cause for concern as I continue writing and building code utilizing this class?
Additions:
There is no source code because there are no source code errors ... this is a question
that does not require presence of source code.
The compiler complained when the copy constructors were private so I made them public; will make private again and verify if compiler hick-ups.
I am using Visual Studio 2012 Professional IDE and its' associated compilers.
Why is the compiler generating copy constructors in the presence of move constructors? Seems counter-intuitive especially if copy constructors are not defined in the fist place.
Additional Question:
Well, it seems Visual Studio 2012 does not support = delete declarations on constructors or assignment operators and hiding my declarations causes the compiler to cry all over my code. What do I do now? I agree (below) that declaring do-nothing copy constructors is bad idea so what other options do I have?
If truly desiring small example, here it is. My compiler does not support = delete
class Tree{
class TreeNode{
"declaration of unique_ptr, cstrs, move cstrs, hidden copy cstrs"
};
public:
"declaration of unique_ptrs, cstrs, move cstrs, copy cstrs <----- compiler
complains if hidden"
};
Using boost::variant with this
Upvotes: 0
Views: 504
Reputation: 254631
Why would the compiler feel the need to synthesize a copy constructor and then complain that
std::unique_ptr
has private members?
It shouldn't, unless your standard library is non-compliant, and declares a private rather than deleted copy-constructor for unique_ptr
; even then, it should only be synthesised if you haven't declared a move constructor.
If your class has unique_ptr
members, or if you declare a move constructor, then it should complain that the copy constructor is deleted; and then only if you write code that attempts to copy it.
Should the compiler not be aware that hidden copy and assignment with no body or simply not defined are to prevent trying to copy a
std::unique_ptr
?
That's right; except that the synthesised copy constructor and assignment are deleted, rather than not defined.
And, why does declaring and defining copy constructors and assignment operators with an empty body make the compiler happy?
Because you are explicitly saying that you want it to use that (empty) code for copying, rather than whatever code it might (or might not) generate implicitly. It's a bad idea though; if your class is not copyable, then you want an attempt to copy it to generate an error, rather than incorrect runtime behaviour.
Upvotes: 1
Reputation: 9969
If there isn't a copy constructor, the compiler will attempt to generate one. The default copy constructor is pretty dumb, so it's not surprising it's tripping over bits of your class.
Defining an empty one gives you a copy constructor that doesn't do anything, and this replaces the one the compiler would otherwise have generated, thus avoiding the problem.
Upvotes: 2