问题描述
让我们说,出于我自己的原因,我希望一个类具有一个非静态引用成员.我认为应该从使用它的大多数代码中轻松优化此类型.因此,我在单元测试中断言了它的微不足道.
Let's say, for reasons of my own, I want a class to have a non-static reference member. I would think that this type should be easily optimized out of most code that uses it. Therefore, I assert its triviality in a unit test.
Clang和GCC同意该类是微不足道的,但MSVC则不同意.根据标准,谁是正确的,为什么是正确的?
Clang and GCC agree that the class is trivial, but MSVC disagrees. Who is right, and why, according to the standard?
#include <type_traits>
struct example {
int& r;
};
// Clang and GCC let this pass
// MSVC fires this assertion
static_assert(
std::is_trivial<example>::value,
"example is not trivial"
);
推荐答案
根据C ++ 17 [class]/6,对于一个琐碎的类,除其他要求外,它至少必须具有一个未删除的类默认构造函数. example
类的默认构造函数被删除,因此example
并不是一个简单的类.
According to C++17 [class]/6, for a class to be trivial, among other requirements, it has to have at least one non-deleted default constructor. The example
class's default constructor is deleted, so example
is not a trivial class.
在C ++ 17之前,情况还不太清楚.平凡的类需要具有平凡的默认构造函数,并且尚不清楚是否删除的默认构造函数符合条件.理查德·史密斯(Richard Smith)在 CWG 1928 中询问,默认和隐式删除的特殊成员函数是否微不足道.委员会的答复是:
Before C++17, the situation is somewhat less clear. It was required for a trivial class to have a trivial default constructor, and it was not clear whether a deleted default constructor qualifies as trivial. Richard Smith asked in CWG 1928 whether special member functions that are defaulted and implicitly deleted are trivial. The Committee's response was:
随后, CWG 1496 的分辨率解决了普通类的问题:不再重要删除的默认构造函数可以认为是微不足道的,因为在C ++ 17中,定义表明 all 所有默认构造函数(如果有多个)必须琐碎或删除,并且至少一个必须被删除.
Subsequently, the resolution of CWG 1496 resolved this issue in the case of trivial classes: it no longer matters whether a deleted default constructor qualifies as trivial, because in C++17, the definition says that all default constructors (in case there are multiple) must be either trivial or deleted and at least one must be non-deleted.
似乎GCC和Clang可能一直在考虑将删除的默认构造函数视为琐碎的事情,并且尚未使用琐碎的类"的C ++ 17定义进行更新.您应该提交错误报告.
It seems that GCC and Clang may have been considering deleted default constructors as trivial, and haven't been updated with the C++17 definition of "trivial class". You should file bug reports.
这篇关于参考班级成员琐事的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!