std :: is_trivially_copyable错了吗?

时间:2018-06-06 12:09:22

标签: c++ c++17 typetraits c++-standard-library

考虑cppreference和当前的c ++工作草案,如果出现以下情况,则可以轻松复制一个类:

  1. 每个复制构造函数都很简单或被删除
  2. 每个移动构造函数都很简单或被删除
  3. 每个复制赋值运算符都是微不足道的或已删除
  4. 每个移动分配操作符都很简单或被删除
  5. 至少有一个复制构造函数,移动构造函数,复制赋值运算符或移动赋值运算符未被删除
  6. 琐碎的未删除的析构函数

  7. 所以我想出了这个代码示例:

    #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 个答案:

答案 0 :(得分:10)

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

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

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

据我所知,标准变更的一个核心动机是使memcpy - 围绕原子和互斥体非法。