Является ли std :: is_trivially_copyable неправильным?

Учитывая cppreference и текущий c++ рабочий проект, класс тривиально можно копировать, если:

  1. Каждый конструктор копирования тривиально или удален
  2. Каждый конструктор перемещения тривиален или удален
  3. Каждый оператор присваивания экземпляра тривиально или удален
  4. Каждый оператор назначения перемещения тривиален или удален
  5. по крайней мере, один конструктор копирования, конструктор перемещения, оператор присваивания копии или оператор присваивания перемещения не удаляются
  6. Тривиальный не удаленный деструктор

Поэтому я придумал этот пример кода:

#include <type_traits>

struct non_trivially_copyable {
  non_trivially_copyable(non_trivially_copyable const&) = delete;
  non_trivially_copyable& operator=(non_trivially_copyable const&) = delete;
  non_trivially_copyable(non_trivially_copyable &&) = delete;
  non_trivially_copyable& operator=(non_trivially_copyable &&) = delete;
};

int main()
{
    return std::is_trivially_copyable<non_trivially_copyable>::value;
}

Мой класс не удовлетворяет требованию номер 5. Тем не менее он дает мне результат, который мой класс non_trivially_copyable тривиально можно копировать. Я тестировал его на некоторых онлайн-компиляторах:

Я сомневаюсь, что все реализации ошибочны; так почему я получаю этот результат?

Ответ 1

Это было изменено в C++ 17; до этого, non_trivially_copyable был бы тривиально скопируемым. Ваш класс действительно не тривиально копируется в C++ 17, частью стандарта, который вы называете самим собой.

Однако, похоже, libstdc++ и libc++ не были обновлены, чтобы отразить это. Поэтому, чтобы ответить на ваш вопрос напрямую: эти две реализации действительно ошибаются. Обратите внимание, что ваша ссылка godbolt показывает, что MSVC делает это правильно.

Поскольку это считалось дефектом (см. CWG 1734), это должно измениться и для реализаций более старых версий C++.


Насколько я знаю, одной из основных причин изменения стандарта было создание незаконного доступа memcpy -ing к атомам и мьютексам.