std::is_trivially_copyable错了吗?
Is std::is_trivially_copyable wrong?
考虑到 cppreference 和当前的 c++ 工作草案,如果满足以下条件,class 是可简单复制的:
- 每个复制构造函数都是微不足道的或已删除
- 每个移动构造函数都是微不足道的或已删除
- 每个复制赋值运算符都是微不足道的或被删除的
- 每个移动赋值运算符都是微不足道的或已删除
- 至少一个复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符未被删除
平凡的非删除析构函数
所以我想出了这个代码示例:
#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;
}
我的 class 不满足第 5 条要求。它仍然给我的结果是我的 class non_trivially_copyable
是微不足道的可复制的。我在一些在线编译器上测试了它:
- https://godbolt.org/g/9s4fr9
- https://wandbox.org/permlink/sEJYdi5aIDMzsjGY
- https://onlinegdb.com/SyFyTBrx7
- http://coliru.stacked-crooked.com/a/93b6ea4d202092a6
我怀疑所有的实现都是错误的;为什么我会得到这个结果?
这在 C++17 中已更改;在此之前,non_trivially_copyable
可以轻松复制。你的 class 在 C++17 中确实不可复制,根据你自己引用的标准部分。
但是,libstdc++ 和 libc++ 似乎尚未更新以反映这一点。所以直接回答你的问题:这两个实现确实是错误的。
请注意,您的 godbolt link 表明 MSVC 确实正确。
由于这被认为是一个缺陷(参见 CWG 1734),因此对于旧版本 C++ 的实现,这也应该有所改变。
据我所知,改变标准的一个核心动机是使 memcpy
-ing 绕过原子和互斥锁是非法的。
考虑到 cppreference 和当前的 c++ 工作草案,如果满足以下条件,class 是可简单复制的:
- 每个复制构造函数都是微不足道的或已删除
- 每个移动构造函数都是微不足道的或已删除
- 每个复制赋值运算符都是微不足道的或被删除的
- 每个移动赋值运算符都是微不足道的或已删除
- 至少一个复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符未被删除
平凡的非删除析构函数
所以我想出了这个代码示例:
#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;
}
我的 class 不满足第 5 条要求。它仍然给我的结果是我的 class non_trivially_copyable
是微不足道的可复制的。我在一些在线编译器上测试了它:
- https://godbolt.org/g/9s4fr9
- https://wandbox.org/permlink/sEJYdi5aIDMzsjGY
- https://onlinegdb.com/SyFyTBrx7
- http://coliru.stacked-crooked.com/a/93b6ea4d202092a6
我怀疑所有的实现都是错误的;为什么我会得到这个结果?
这在 C++17 中已更改;在此之前,non_trivially_copyable
可以轻松复制。你的 class 在 C++17 中确实不可复制,根据你自己引用的标准部分。
但是,libstdc++ 和 libc++ 似乎尚未更新以反映这一点。所以直接回答你的问题:这两个实现确实是错误的。 请注意,您的 godbolt link 表明 MSVC 确实正确。
由于这被认为是一个缺陷(参见 CWG 1734),因此对于旧版本 C++ 的实现,这也应该有所改变。
据我所知,改变标准的一个核心动机是使 memcpy
-ing 绕过原子和互斥锁是非法的。