This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 2827. `is_trivially_constructible` and non-trivial destructors

Section: 21.3.5.4 [meta.unary.prop] Status: New Submitter: Richard Smith Opened: 2016-11-17 Last modified: 2020-01-25

Priority: 3

View other active issues in [meta.unary.prop].

View all other issues in [meta.unary.prop].

View all issues with New status.

Discussion:

>     struct S
>     {
>       ~S(); // non-trivial
>     };

>     static_assert(std::is_trivially_constructible<S>::value, "");

Should the assert pass? Implementations disagree.

Per 21.3.5.4 [meta.unary.prop]'s Table 38, this trait looks at whether the following variable definition is known to call no operation that is not trivial:

>     S t(create<Args>()...);

... where `Args` is an empty pack in this case. That variable definition results in a call to the `S` destructor. Should that call be considered by the trait?

[2017-01-27 Telecon]

Priority 3

This issue interacts with 2116

[2020-01-24; Peter Dimov comments]

`std::is_trivially_copy_constructible_v<D>`, where `D` is

>     struct D
>     {
>       ~D() {}
>     };

reports `false`. This is because the definition of `is_trivially_copy_constructible` requires the invented variable definition `T t(declval<Args>()...);`, which in our case is `D t(declval<D>());`, to not call any nontrivial operations.

This is interpreted by implementations to include the destructor call, presumably for consistency with `is_nothrow_copy_constructible`. But that's wrong; the copy constructor is trivial.

As a consequence, `variant<D>` also doesn't have a trivial copy constructor, which causes (completely unnecessary) inefficiencies when said `variant` is copied.

Proposed resolution: