is_trivially_constructible and non-trivial destructors
Richard Smith

Created on 2016-11-17.00:00:00 last changed 13 months ago


Date: 2023-05-15.00:00:00

[ 2023-05-25; May 2023 mailing ]

Alisdair provided P2842R0.

Date: 2020-01-15.00:00:00

[ 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.

Date: 2017-01-27.00:00:00

[ 2017-01-27 Telecon ]

Priority 3

This issue interacts with 2116

Date: 2016-11-17.00:00:00
struct S 
  ~S(); // non-trivial

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

Should the assert pass? Implementations disagree.

Per [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?

Date User Action Args
2023-05-25 14:42:27adminsetmessages: + msg13583
2020-01-25 15:17:35adminsetmessages: + msg10966
2017-01-30 15:17:53adminsetmessages: + msg8805
2016-11-17 00:00:00admincreate