I want my C++ type to expose a move-only interface, therefore I declared its copy constructor and copy assignment as deleted. Nonetheless, the move constructor and move assignment are trivial, and the destructor is also trivial, therefore it is considered as "trivially_copyable" for the C++ standard. This is a problem, because copying an object of this type really is semantically wrong.
A possible solution is to user-define an empty destructor that does nothing. This makes the type not "trivially_copyable", but as a consequence the type is not longer "trivial for the purposes of calls" for the Itanium ABI, which can have negative performance implications.
Is there a way to achieve all these goals at the same time? The type should have trivial move-constructor, move-assignment and destructor. The type should not be trivially copyable. The type should be trivial for the purpose of calls for the Itanium ABI.
https://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial
[class.prop]p1:
So all the copy/move constructors and the destructor have to remain non-trivial, so you can only make it not trivially copyable with a copy or move assignment operator. Since you want the move assignment operator to be trivial, that leaves a copy assignment operator:
This can also be solved with
[[clang::trivial_abi]]:But that is only available with Clang (which modifies the definition of "non-trivial for the purposes of calls" to exclude classes with this attribute)