【发布时间】:2012-10-05 22:33:26
【问题描述】:
std::is_trivially_copyable 在这两个编译器中仍然不受支持(至少就 gcc 4.6 而言)。但两者都提供了做得很好的__has_trivial_copy 指令。
除非涉及到已删除的复制构造函数。
struct A { A(A const&) =delete; };
__has_trivial_copy(A) 在 clang 中返回 1,在 gcc 中返回 0。
我正在研究标准,找不到一个子句说明在删除复制构造函数时该类是否仍被视为可简单复制。
谁是对的?
我倾向于相信 gcc 是正确的,因为 struct A 根本不可复制,更不用说可复制了。此外,还有一个广泛的共识,即删除的复制构造函数可以被视为私有声明但未定义的构造函数,在这种情况下 gcc 仍然是正确的。
另一方面,第 9/6 节中的标准描述了不具有任何非平凡操作的平凡可复制性。我想如果您按照书面标准阅读,clang 可能是对的。
【问题讨论】:
-
__has_trivial_copy(type)的规格是什么??A当然是可以简单复制的(memcpy是它的一个实例没有问题)。肯定有一些std::is_foobar类型特征与核心语言 foobary 规范“矛盾”,但 C++ 标准中没有定义__has_trivial_copy。 -
来自 gcc 文档: __has_trivial_copy (type) 如果 __is_pod (type) 为 true 或 type 是引用类型,则 trait 为 true,否则如果 type 是 cv 类或带有普通副本的联合类型构造函数 ([class.copy]) 则特征为真,否则为假。要求:类型应为完整类型、(可能是 cv 限定的)void 或未知边界数组。
-
永远不要直接使用编译器钩子,你只是在问麻烦。只需使用
std::is_trivially_copyable。 -
恐怕当这两个编译器都引入std::is_trivially_copyable时,他们会简单地使用当前的机制,这是不兼容的。我明白 A 是可记忆的。
-
从 gcc 文档的外观来看,
__has_trivial_copy听起来与std::is_trivially_copy_constructible的关系比std::is_trivially_copyable更密切。但别担心,g++ 库的家伙比只使用旧扩展并假设它是正确的更聪明。