What types are trivially constructible?

Viewed 1771

I know, that many types (e.g. POD types) are trivially default-constructible. But what types are trivially constructible from an argument list other than the empty argument list? For example what types are trivially constructible from int? I can't think of any.

The following types are not trivially constructible from int in C++17 (live demo):

#include <type_traits>

struct X { int x; };
struct Y { Y(int) {} };
struct Z { Z(int) = delete; };

static_assert(std::is_trivially_constructible<X, int>::value == false);
static_assert(std::is_trivially_constructible<Y, int>::value == false);
static_assert(std::is_trivially_constructible<Z, int>::value == false);
2 Answers

Trivially constructible from Args... is defined as construction from values of the given types that does only do operations considered "trivial". In particular the syntax T obj(std::declval<Args>()...) has to call only "trivial" operations.

Up until C++17 the only trivial construction operations possible are default construction, copy construction, and move construction. So if a set of parameters invokes any other constructor or does any other operation as part of doing that construction, such a call cannot be trivial. Therefore in C++17 std::is_trivially_constructible_v<T, int> can only be true with T = int (int is trivially copyable from itself).

From C++20 on, which implements P0960 "Allow initializing aggregates from a parenthesized list of values" std::is_trivially_constructible_v<X, int> is true. See live demo. This is because the syntax X obj(std::declval<int>()) calls only trivial operations, which satisfies the requirement of the type trait.

Trivially constructible from is defined as construction from values of the given types that does not do any operation not considered "trivial" (see paragraph 2 here). int is a trivially copyable type, so int is trivially copyable from itself. Therefore, std::is_trivially_constructible_v<int, int> is true.

The only trivial operations possible are default construction, copy construction, and move construction. So if a set of parameters invokes any other constructor or does any other operation as part of doing that construction, such a call cannot be trivial.

Related