这两个编译器中的任何一个都不支持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是正确的,因为结构A根本不可复制,更不用说可以复制了.此外,还有一个广泛的共识,即删除的拷贝构造函数可以被视为私有声明但未定义的构造函数,在这种情况下gcc仍然是正确的.
另一方面,第9/6节中的标准描述了没有任何非平凡操作的简单可复制性.我想如果你按标准阅读标准,铿锵可能是正确的.
解决方法
libc,clang的本机库,支持std :: is_trivially_copyable< T>事实上,假装你的例子,这种类型是可以轻易复制的,尽管它显然不是轻易复制的.我认为,12.8 [class.copy]第12段将删除的构造函数定义为非平凡的:
A copy/move constructor for class X is trivial if it is not user-provided …
删除的声明显然是用户提供的.当我在这里说“清楚”时,我的意思是我不能立即通过宣布删除函数的标准来支持它计为用户提供的…
进一步的调查显示,8.4.2 [dcl.fct.def.default]第4段(感谢Jesse Good提供参考)使得非用户提供的删除功能:
… A special member function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. …
因此,如果没有其他理由可以进行非平凡的可复制,那么具有已删除的复制构造函数的类确实可以轻易地复制(但这些都不适用于问题中的类型A.这有点奇怪:类型类型无法使用它的复制构造函数,但它可以使用std :: memcpy()复制!我不确定这是否真的是故意的.