Title
Nontrivial deleted copy functions
Status
cd4
Section
15.8 [class.copy]
Submitter
James Widman

Created on 2013-08-09.00:00:00 last changed 42 months ago

Messages

Date: 2015-10-15.00:00:00

Proposed resolution (October, 2015):

Change 12 [class] paragraph 6 as follows:

A trivially copyable class is a class that:

  • has no non-trivial copy constructors (15.8 [class.copy]),

  • has no non-trivial move constructors (15.8 [class.copy]),

  • has no non-trivial copy assignment operators (16.5.3 [over.ass], 15.8 [class.copy]),

  • has no non-trivial move assignment operators (16.5.3 [over.ass], 15.8 [class.copy]), and

  • where each copy constructor, move constructor, copy assignment operator, and move assignment operator (15.8 [class.copy], 16.5.3 [over.ass]) is either deleted or trivial,

  • that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and

  • that has a trivial, non-deleted destructor (15.4 [class.dtor]).

Date: 2015-11-10.00:00:00

Additional note, October, 2015:

Moved from "extension" to "open" status, along with issue 1928, to allow reconsideration by CWG. It has been suggested that the triviality of a deleted function should be irrelevant, since it cannot be used in any event. A possible change to implement that, more conservative than the one proposed in N4148, would be:

A trivially copyable class is a class that:

  • has no non-trivial, non-deleted copy constructors (15.8 [class.copy]),

  • has no non-trivial, non-deleted move constructors (15.8 [class.copy]),

  • has no non-trivial, non-deleted copy assignment operators (16.5.3 [over.ass], 15.8 [class.copy]),

  • has no non-trivial, non-deleted move assignment operators (16.5.3 [over.ass], 15.8 [class.copy]),

  • has at least one non-deleted copy or move constructor or assignment operator, and

  • has a trivial, non-deleted destructor (15.4 [class.dtor]).

Date: 2014-11-24.00:00:00

Additional note, November, 2014:

See paper N4148.

Date: 2016-02-15.00:00:00

[Adopted at the February, 2016 meeting.]

The intent was for PODs in C++11 to be a superset of C++03 PODs. Consequently, in the following example, C should be a POD but isn't:

  struct A {
    const int m;
    A& operator=(A const&) = default; // deleted and trivial, so A is a
                                      // POD, as it would be in 2003
                                      // without this explicit op= decl
  };
  static_assert(__is_trivially_copyable(A), "");

  struct B { 
    int i; 
    B& operator=(B &) & = default;      // non-trivial
    B& operator=(B const&) & = default; // trivial
  };

  struct C {
    const B m;
    C& operator=(C const& r) = default; // deleted (apparently), but non-trivial (apparently)
    /* Notionally:
      C& operator=(C const& r) {
        (*this).m.operator=(r.m);
        return *this;
      }
    */
  };
  static_assert(!__is_trivially_copyable(C), "");  

This is because of the following text from 15.8 [class.copy] paragraph 25:

for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial;

In this case, overload resolution fails, so no assignment operator is selected, so C::operator=(const C&) is non-trivial.

(See also issue 1928.)

History
Date User Action Args
2017-02-06 00:00:00adminsetstatus: extension -> cd4
2015-11-10 00:00:00adminsetmessages: + msg5582
2015-11-10 00:00:00adminsetmessages: + msg5581
2015-11-10 00:00:00adminsetstatus: drafting -> extension
2015-05-25 00:00:00adminsetstatus: ready -> drafting
2014-11-24 00:00:00adminsetmessages: + msg5214
2013-10-14 00:00:00adminsetstatus: open -> ready
2013-08-09 00:00:00admincreate