c++之具有引用成员的结构是否具有唯一的对象表示
此 answer提出了以下问题。
假设我们有一个简单的
struct S {
int& i;
}
内部(至少在 GCC 和 Clang 中)
S
只包含一个指向
int
的指针, 和
static_assert(sizeof(int*) == 8);
static_assert(sizeof(S) == 8);
是否
S
有一个独特的对象表示? GCC 和 Clang 不同意 *:
static_assert( std::has_unique_object_representations_v<int*>);
static_assert(!std::has_unique_object_representations_v<S>); // GCC
static_assert( std::has_unique_object_representations_v<S>); // Clang
哪个编译器就在这里,为什么?
* 指出 GCC 和 Clang 之间的分歧idclev 463035818 .
请您参考如下方法:
首先,引用不是对象。对象在 [intro.object] 中指定,引用在 [dcl.ref] 中。
子对象是对象([intro.object])。因此引用成员不是子对象,因此只包含引用成员(没有基类)的类没有子对象(即使它有数据成员)。
[meta.unary.prop]
The predicate condition for a template specialization has_unique_object_representations shall be satisfied if and only if:
- T is trivially copyable, and
- any two objects of type T with the same value have the same object representation, where two objects of array or non-union class type are considered to have the same value if their respective sequences of direct subobjects have the same values, ...
子对象的序列是空的,因此等于另一个空序列,因此等于
S
类型的所有对象。根据此规则具有“相同值”2。
但是,引用不同对象的对象必然具有不同的对象表示。因此,第二个要求是 不是 1 满意。
因此对象表示不是唯一的,Clang 在技术上是错误的,而 GCC 和 MSVC(与 GCC 具有相同的结果)是正确的。
如果我们得出不满足第二个要求的结论,这已经变得有点离题了,但是:是
S
微不足道的复制?
static_assert(std::is_trivially_copyable_v<S>);
在 Clang 和 GCC 中都通过,但根据 MSVC,
S
是
不是 可复制。那么,哪个是正确的?
[class.copy.ctor]
A copy/move constructor for class X is trivial if it is not user-provided and if:
- class X has no virtual functions ([class.virtual]) and no virtual base classes ([class.mi]), and
- the constructor selected to copy/move each direct base class subobject is trivial, and
- for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
这些都满足了。因此
S
有一个简单的复制/移动构造函数。
[class.prop]
A trivially copyable class is a class:
- that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator ([special], [class.copy.ctor], [class.copy.assign]),
- where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
- that has a trivial, non-deleted destructor ([class.dtor]).
一切都很满意,因此
S
是 微不足道的可复制,而 MSVC 类型特征相反地陈述是错误的。
1 编辑:我最初得到了反向结论。
2 在考虑类对象的“值”时是否应该忽略引用数据成员在我看来是有争议的。这种忽略它们的技术性可能被视为标准中的缺陷。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。