__has_trivial_copy在clang和gcc中的行为不同。谁是对的? [英] __has_trivial_copy behaves differently in clang and gcc. Who's right?
问题描述
std :: is_trivially_copyable
(至少gcc 4.6)。但两者都提供 __ has_trivial_copy
指令,做得很好。
除非涉及到删除的复制构造函数。
struct A {A(A const&)= delete; };
__ has_trivial_copy(A)
我正在挖掘标准,找不到一个子句,说明当复制构造函数被删除时,该类是否仍然被认为是可复制的。 / p>
谁是对的?
我的倾向是相信gcc是正确的,因为 struct A
根本不可复制,更不用说可复制。还有一个广泛的共识,一个删除的副本构造函数可以看作是一个私有声明,但没有定义的构造函数,在这种情况下gcc仍然是正确的。
另一方面,第9/6节中的标准描述了在没有任何非平凡操作方面的平凡可复制性。
libc ++,clang的本机库,支持 std :: is_trivially_copyable< T>
,并且,实际上,假装你的例子类型是平凡可复制,虽然它显然不是可微不足道的可复制。我认为,12.8 [class.copy]第12段将删除的构造函数定义为不重要的:
类X的复制/移动构造函数如果不是用户提供的话,它是微不足道的...
删除的声明显然是用户提供的。当我在这里说清楚我的意思是,我不能立即备份它的标准,声明一个函数为删除计数为用户提供...
进一步的调查显示,8.4.2 [dcl.fct.def.default]第4段(感谢Jesse Good提供参考)使得非用户提供的已删除功能:
...如果是用户声明的,并且没有在其第一个声明中显式默认或删除,则特殊成员函数是用户提供。 ...
因此,如果没有其他原因使得一个具有删除的拷贝构造函数的类确实是可复制的可复制(但是这些都不适用于问题中的 A
类型。这有点奇怪:类型类型不能使用其副本构造函数复制,但它<使用 std :: memcpy()
复制。
std::is_trivially_copyable
is still not supported in either of those two compilers (at least as far as gcc 4.6). But both provide __has_trivial_copy
directives that do pretty good job.
Except when it comes to deleted copy constructors.
struct A { A(A const&) =delete; };
__has_trivial_copy(A)
returns 1 in clang and 0 in gcc.
I was digging in the standard and could not find a clause that says whether the class is still considered trivially copyable when the copy constructor is deleted.
Who's right?
My inclination is to believe that gcc is right, because struct A
is not copyable at all, let alone trivially copyable. Also, there's a wide-spread consensus, that a deleted copy constructor can be seen as a privately declared, but not defined constructor, in which case gcc would still be right.
On the other hand, the standard in section 9/6 describes trivial-copyability in terms of not having any non-trivial operations. I guess if you read the standard as written, clang may be right.
libc++, clang's native library, supports std::is_trivially_copyable<T>
and, indeed, pretends on your example that the type is trivially copyable although it is clearly not trivially copyable. I think, 12.8 [class.copy] paragraph 12 defines the deleted constructor as non-trivial:
A copy/move constructor for class X is trivial if it is not user-provided ...
The deleted declaration is clearly user-provided. When I say "clearly" here I mean that I can't immediately back it up by the standard that declaring a function as deleted counts as user-provided...
Further investigation reveals that 8.4.2 [dcl.fct.def.default] paragraph 4 (thanks to Jesse Good for providing the reference) makes a deleted function non-user-provided:
... A special member function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. ...
Thus, a class with a deleted copy constructor is indeed trivially copyable if there is no other reason to make non-trivially copyable (but none of those applies to the type A
in the question. That's a bit weird: type type cannot be copied using its copy constructor but it can be copied using std::memcpy()
! I'm not sure if this is really intentional.
这篇关于__has_trivial_copy在clang和gcc中的行为不同。谁是对的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!