c++type-traitsc++26trivially-copyable

Why is std::is_trivial deprecated in C++26?


std::is_pod is deprecated since C++20 and the answer to this question tells us that we should use std::is_standard_layout + std::is_trivial instead.

However, with C++26, now also std::is_trivial is deprecated. Why is that and what should we use instead?


Solution

  • This change comes from P3247: Deprecate the notion of trivial types. The problem with std::is_trivial is that it mixes two different checks:

    std::is_trivial is somewhat useless

    These two checks are used in different situations, so having them bunched together into a single trait isn't very useful. For example, a container that explicitly manages lifetimes of objects stored in a std::byte[] (likestd::vector)

    Knowing whether a type is trivial is somewhat useless because we're typically interested in more specific properties. Of course, there are some rare situations where we want to know both properties and std::is_trivial provides a bit of convenience, but it's not a lot of work to just ask for trivial copyability and trivial default construction separately.

    std::is_trivial may be a pitfall

    A developer may assume that if std::is_trivial is true, a type is "totally trivial" in every regard, including assignment. However, the proposal provides a counter-example:

    struct S {
      const int i;
    };
    

    S is trivially copyable, yet it is not assignable. A user seeking to replace copy-assignment with memcpy should use is_trivially_copy_assignable for the check; checking just is_trivial or is_trivially_copyable as a precondition for assignment would underconstrain the user code.

    Note that S is trivial, in case this wasn't clear.