std :: is_trivially_copyable错了吗?

phö*_*hön 11 c++ type-traits c++-standard-library c++17

考虑到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;
}
Run Code Online (Sandbox Code Playgroud)

我的班级不满足要求编号5.它仍然给我的结果是我的班级non_trivially_copyable可以轻易复制.我在一些在线编译器上测试了它:

我怀疑所有的实现都是错误的; 那为什么我得到这个结果呢?

Bau*_*gen 10

这在C++ 17中有所改变; 在此之前,non_trivially_copyable本来可以轻易复制.你的课程在C++ 17中确实不是可以复制的,而是你自己提到的标准部分.

但是,似乎libstdc ++和libc ++没有更新以反映这一点.所以直接回答你的问题:这两个实现确实是错误的.请注意,您的Godbolt链接显示MSVC确实正确.

由于这被认为是一个缺陷(参见CWG 1734),这也应该改变C++旧版本的实现.


据我所知,标准变化的一个核心动机是使memcpy原子和互斥体成为非法的.