A deleted default constructor could still be trivial?

后端 未结 1 1675
悲哀的现实
悲哀的现实 2021-02-04 03:40

Looking at the definition of trivial default constructor in the standards:

A default constructor is trivial if it is not user-provided and if:

1条回答
  •  有刺的猬
    2021-02-04 03:50

    CWG issue 667 addressed this exact issue with a change that was incorporated into the C++ working draft near N3225. N3225 § 12.1 [class.ctor]/5 states:

    A default constructor is trivial if it is neither user-provided nor deleted and if:

    • its class has no virtual functions (10.3) and no virtual base classes (10.1), and
    • no non-static data member of its class has a brace-or-equal-initializer, and
    • all the direct base classes of its class have trivial default constructors, and
    • for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.

    Otherwise, the default constructor is non-trivial.

    This was (obviously) changed before C++11 release. CWG DR 1135 was created to address a Finland national body comment on the C++11 candidate draft:

    It should be allowed to explicitly default a non-public special member function on its first declaration. It is very likely that users will want to default protected/private constructors and copy constructors without having to write such defaulting outside the class.

    The resolution of this issue removed the "nor deleted" text from 12.1 as well as the sections describing trivial destructors, trivial copy/move constructors, and trivial copy/move assignment operators. I think this change cut too broad a swath, and it was likely not intentional to make your struct A trivial. Indeed, on face value it's ridiculous that this program is ill-formed:

    int x = 42;
    int y = 13;
    A a_x{x};
    A a_y{y};
    a_x = a_y;
    

    but this program is not, since A is trivially copyable (Clang agrees, GCC does not):

    int x = 42;
    int y = 13;
    A a_x{x};
    A a_y{y};
    std::memcpy(&a_x, &a_y, sizeof(a_x));
    

    The existence of CWG issue 1496 "Triviality with deleted and missing default constructors" seems to indicate that the committee is aware of the problem (or at least a closely related problem):

    A default constructor that is defined as deleted is trivial, according to 12.1 [class.ctor] paragraph 5. This means that, according to 9 [class] paragraph 6, such a class can be trivial. If, however, the class has no default constructor because it has a user-declared constructor, the class is not trivial. Since both cases prevent default construction of the class, it is not clear why there is a difference in triviality between the cases.

    although there is no resolution as yet.

    0 讨论(0)
提交回复
热议问题