以下代码打印是否std::atomic<bool>
可简单复制:
#include <atomic>
#include <iostream>
#include <type_traits>
int main(){
std::cout << std::is_trivially_copyable_v<std::atomic<bool>> << "\n";
}
它在 gcc 和 clang 上给出以下结果:
1
但在 MSVC 上的结果是:
0
还使用演示了所有 3 个编译器的行为static_assert
。
我认为标准以任何一种方式定义了平凡的可复制性。
哪个编译器是正确的(或者是特定于实现的)?
2
3 个回答
3
另请参阅:
删除的构造函数并非不重要。
在的决议之前,要实现简单复制,所有复制/移动构造函数/赋值运算符都必须是简单的。是这样的std::atomic<bool>
(都被删除了)
使用新的措辞,也必须不删除(在 C++20 中,“合格”,因为满足其约束)。
GCC 和 Clang 没有实现这一点。请参阅:
2
-
这是否意味着 MSVC 就在这里,而 gcc/glang 不兼容?
–
-
7@wohlstad 是的,MSVC 目前是正确的,GCC 和 clang 在 2016 年 2 月之前都是合规的
–
|
问题在于 trivially_copyable 的操作方式。您实际上无法复制 clang 上的原子:
这同样适用于自定义不可复制类型。因此,唯一的问题是是否允许 trivially_copyable 对于不可复制类型返回 true。也许有人会说,由于该类型无法复制,因此它没有重要的复制操作。虽然我自己的直觉是 is 应该给出“false” – 否则你必须在某些情况下检查 is_copyable 以及 trivally_copyable 。对标准有更多了解的人可能能够回答这个问题 – 我只能说,基于 Cpp-reference (),我没有看到任何本案例的要求。
1
-
谢谢回答。尽管我可以从您所写的内容中看到原因,但我对可复制性和琐碎可复制性之间的依赖关系并不乐观。请参阅 Nifil 答案下的评论。
–
|
评论跟进:
声明“std::atomic 既不可复制也不可移动。”我建议遵循标准。
另外查看我们发现复制运算符已被删除。
关于 std::is_trivially_copyable_v 的返回值,我认为 @Juliean 的答案提供了一个很好的解释
6
-
1先验的不可复制(即没有可行的复制构造函数)并不意味着
std::trivially_copyable
必须是false
。 “简单可复制”是指通过复制字节进行复制,即绕过复制构造函数。
–
-
谢谢回答。但我认为,如上所述,琐碎的可复制性是一个与“正常”可复制性/可移动性分开的概念。
– -
@wohlstad 我从这里获取了定义 /… 一个简单可复制的类是一个至少有一个合格的复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符的类,每个合格的复制构造函数是平凡的 每个合格的移动构造函数都是平凡的 每个合格的复制赋值运算符都是平凡的 每个合格的移动赋值运算符都是平凡的,并且具有未删除的平凡析构函数。
– -
2恕我直言,你应该在答案中引用这句话。请注意,我并不是说你错了。我只是说你的答案做了一个无声的假设,如果一个类型不能通过复制构造函数复制,那么它就不能被简单地复制,我不认为这是显而易见的,它应该是答案的一部分。
–
-
1顺便说一句,据我理解,当一个类有一个移动构造函数但没有其他移动或复制时就足够了,并且如果该移动构造函数很简单,那么其他项目符号也将被覆盖。 (仍然不是说你错了,只是想澄清我自己的困惑)
–
|
–
–
|