https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96288

--- Comment #1 from Matt Whitlock <gcc at mattwhitlock dot name> ---
The following workaround seems to implement the standard's intended definition
of std::is_trivially_copyable:


template <typename T>
struct is_actually_trivially_copyable :
        std::bool_constant<
                std::is_trivially_copyable_v<T> && (
                        std::is_trivially_copy_constructible_v<T> ||
                        std::is_trivially_move_constructible_v<T> ||
                        std::is_trivially_copy_assignable_v<T> ||
                        std::is_trivially_move_assignable_v<T>
                )
        >
{ };

template <typename T>
static constexpr bool is_actually_trivially_copyable_v =
        is_actually_trivially_copyable<T>::value;


When I use the above instead of std::is_trivially_copyable, then my function
overloads that are constrained to apply only to trivially copyable types no
longer apply to classes that define no non-deleted special member functions,
which std::is_trivially_copyable is erroneously identifying as trivially
copyable types.

Example:

struct NonTrivial {
        int &data;

        constexpr explicit NonTrivial(int &data) noexcept : data(data) { }
        NonTrivial(const NonTrivial &) = delete;
};
static_assert(!is_actually_trivially_copyable_v<NonTrivial>);
static_assert(!std::is_trivially_copyable_v<NonTrivial>); // FAIL!

Reply via email to