<snip>
Both of the above definitions of triviality delegate to something that
is "selected to copy/move" certain subobjects. But if the copy/move
operation is deleted, nothing actually gets selected. That IMO gives
rise to two potential interpretations: On the one hand, as nothing gets
selected, it is irrelevant whether what would be selected if the
copy/move operation were not deleted is trivial (and thus the deleted
copy constructor of S2 is trivial). On the other hand, as nothing gets
selected, the requirement that what gets selected is trivial is not met
(and thus the deleted copy constructor of S2 is non-trivial, as no
trivial constructor is selected to copy the S1 base class subobject).
(Not sure whether this question makes a practical difference for the
standard though, as qualification of (non-)triviality of such copy/move
operations appears to generally by accompanied by some non-deletedness
qualification.)
I agree that it shouldn't matter since all contexts where triviality of a function matters should be ones where the function must not be deleted. This situation is a bit strange for all of the special members. For example, given
struct X { int &r; };
struct Y { int &r; virtual void f(); };
then by the letter of the Standard, X::X() is deleted and trivial while Y::Y() is deleted and non-trivial. But this distinction is pointless.
I'd say by the spirit of the Standard, though the letter contradicts, a deleted function is never trivial. This also fits with the unofficial rule of thumb that evaluating a trivial function is accomplished with zero processor instructions (assuming reasonable optimizations enabled, no runtime linting or similar features, etc.). Of course, evaluating a deleted function is not accomplished at all, so it's not in that category.
-- Andrew Schepler
--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion