Re: Class invariants and implicit move constructors (C++0x)
On 18 Aug., 07:06, Alf P. Steinbach wrote:
Also, crossing the t's, it would be "non-trivial" user defined destructor=
..
According to the FCD's definition of "trivial" there are no trivial
"user-provided" destructors. Also, virtual destructors are never
trivial. (see =A712.4/3)
Because many people (including myself) define destructors for other purpo=
ses
than directly customizing destruction, e.g. to make a class polymorphic.
But how often do you need to copy/move objects of polymorphic classes?
I do like the idea of implicitly generated move ops. But in cases of
classes that need a virtual destructor I can live without implicit
move ops. If that makes the rules simpler, great.
Or just to follow a common coding convention. This then yields a
little problem when the class definition only declares the
destructor and it's defined as trivial in a separately compiled file,
so I think the wording would have to refer to the class definition,
that move ops are only generated automatically when it's /known from
the class definition only/ that no non-trivial destructor is defined
(i.e. the class definition has no user defined destructor or a
destructor is defined with empty body in the class definition).
Since trivial already means something else, the wording might look
like this:
If the class definition does not explicitly declare a move
constructor, one will be implicitly declared as defaulted if and
only if
- X does not have a user-declared copy constructor and
- X does not have any user-declared (copy/move) assignment
operators and
- X does not have a user-declared destructor OR it has an
in-class user-provided destructor with no statements and
- the move constructor would not be implicitly defined as deleted.
Similar for the move assignment operator:
If the class definition does not explicitly declare a move
assignment operator, one will be implicitly declared as defaulted
if and only if
- the copy assignment operator is not user-declared and
- X does not have any user-declared (copy/move) constructors and
- X does not have a user-declared destructor OR it has an
in-class user-provided destructor with no statements and
- the move assignment operator would not be implicitly defined as
deleted.
where "in-class user-provided empty destructor" is not supposed to
rule out virtual destructors.
Finally, regarding previous thinking about this, In N3053 Bjarne Stroustr=
up &
Lawrence Crawl wrote, as 1 point of 4, "Having unnecessarily different ru=
les for
when to generate moves and copies would cause surprising behavior."
However, in this thread examples have been presented, by Scott Meyers and=
me,
that show that having the particular identical-for-copy-and-move rules th=
at were
adopted in the N3090 draft standard, cause surprising behavior, namely in=
correct
Undefined Behavior, by unexpectedly invalidating class invariants in C++9=
8 code.
Thus, AISI the rule you propose is not "unnecessarily different", and not=
in
conflict in with N3090. It's very /necessarily/ different. :-)
Yes. I agree with you. :-)
Cheers!
SG