问题
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 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"
);
回答1:
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.
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 feels that the triviality of a deleted function should be irrelevant. Any cases in which the triviality of a deleted function is observable should be amended to remove that dependency.
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.
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.
来源:https://stackoverflow.com/questions/60876410/reference-class-member-triviality