问题 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 很容易复制。我在一些在线编译器上测试了它:

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


4242
2018-06-06 12:09


起源



答案:


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

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

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


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


10
2018-06-06 12:23



好吧,所以我从概念上说得对:P我猜其他实现会跟随msvc一起使用“正确”的东西吗? - phön
@phön是的,迟早,其他实现也应该符合要求。 C ++ 17仍然很新;通常可能需要一些时间才能完全实现对标准的所有更改。 - Baum mit Augen


答案:


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

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

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


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


10
2018-06-06 12:23



好吧,所以我从概念上说得对:P我猜其他实现会跟随msvc一起使用“正确”的东西吗? - phön
@phön是的,迟早,其他实现也应该符合要求。 C ++ 17仍然很新;通常可能需要一些时间才能完全实现对标准的所有更改。 - Baum mit Augen