Considering cppreference and the current c++ working draft, a class is trivially copyable if:
Trivial non-deleted destructor
So I came up with this code sample:
#include <type_traits>
struct non_trivially_copyable {
non_trivially_copyable(non_trivially_copyable const&) = delete;
non_trivially_copyable& operator=(non_trivially_copyable const&) = delete;
non_trivially_copyable(non_trivially_copyable &&) = delete;
non_trivially_copyable& operator=(non_trivially_copyable &&) = delete;
};
int main()
{
return std::is_trivially_copyable<non_trivially_copyable>::value;
}
My class does not satisfy requirement number 5. Still it gives me the result that my class non_trivially_copyable
is trivially copyable. I tested it on some online compilers:
I doubt that all implementations are wrong; so why do I get this result?
A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.
Trivially copyable types have no non-trivial copy operations, move operations, or destructors. Generally, a copy operation is considered trivial if it can be implemented as a bitwise copy. Both built-in types and arrays of trivially copyable types are trivially copyable.
Trivially constructible from is defined as construction from values of the given types that does not do any operation not considered "trivial" (see paragraph 2 here). int is a trivially copyable type, so int is trivially copyable from itself. Therefore, std::is_trivially_constructible_v<int, int> is true.
This was changed in C++17; before that, non_trivially_copyable
would have been trivially copyable. Your class is indeed not trivially copyable in C++17, by the part of the standard you refer to yourself.
However, it appears libstdc++ and libc++ were not updated to reflect that yet. So to answer your question directly: those two implementations are indeed wrong. Note that your godbolt link shows that MSVC does get it right.
As this was considered a defect (see CWG 1734), this is supposed to change for implementations of older revisions of C++, too.
As far as I know, one core motivation for the change in the standard was to make memcpy
-ing around atomics and mutexes illegal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With