When running this simple program, different behaviour is observed depending on the compiler.
It prints true when compiled by GCC 11.2, and false when compiled by MSVC 19.29.30137 with the (both are the latest release as of today).
#include <type_traits>
#include <iostream>
struct S {
int a;
S() = delete;
S(S const &) = delete;
S(S &&) = delete;
S &operator=(S const &) = delete;
S &operator=(S &&) = delete;
~S() = delete;
};
int main() {
std::cout << std::boolalpha;
std::cout << std::is_trivially_copyable_v<S>;
}
Relevant quotes (from the latest C++23 working draft N4901):
Given 20.15.5.4 [meta.unary.prop], std::is_trivially_copyable_v<T> is defined to be true if T is a trivially copyable type as defined at 6.8.1/9 [basic.types.general]:
Arithmetic types (6.8.2), enumeration types, pointer types, pointer-to-member types (6.8.3), std::nullptr_t, and cv-qualified (6.8.4) versions of these types are collectively called scalar types. Scalar types, trivially copyable class types (11.2), arrays of such types, and cv-qualified versions of these types are collectively called trivially copyable types.
where trivially copyable class types is defined at 11.2/1 [class.prop]:
1 A trivially copyable class is a class:
— that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator (11.4.4, 11.4.5.3, 11.4.6),
— where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
— that has a trivial, non-deleted destructor (11.4.7).
Eligible (11.4.4 [special]):
1 Default constructors (11.4.5.2), copy constructors, move constructors (11.4.5.3), copy assignment operators, move assignment operators (11.4.6), and prospective destructors (11.4.7) are special member functions.
6 An eligible special member function is a special member function for which:
— the function is not deleted,
— the associated constraints (13.5), if any, are satisfied, and
— no special member function of the same kind is more constrained
trivial for these functions (as defined at 11.4.5.3/11 [class.copy.ctor], 11.4.6/9 [class.copy.assign], 11.4.7/8 [class.dtor]) generally means:
- the function is not user-provided.
- there's nothing virtual to the class
- each non-static data member has the relevant trivial function
As per 9.5.2/5 [dcl.fct.def.default], the deleted functions in the provided program aren't user-provided:
... A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. ...
If my understanding is correct, struct S has deleted special member functions making them non-eligible, which doesn't meet the requirements for a trivially copyable class type and trivially copyable type. Therefore the conforming behaviour is MSVC's. Is this correct?