Why can't std :: tuple <int> be trivially copied?
Built with this online compiler , the following code:
#include <iostream> #include <type_traits> #include <tuple> int main() { std::cout << std::is_trivially_copyable<std::tuple<int>>::value << std::endl; std::cout << std::is_trivially_copyable<std::pair<int, int>>::value << std::endl; std::cout << std::is_trivial<std::tuple<int>>::value << std::endl; std::cout << std::is_trivial<std::pair<int, int>>::value << std::endl; return 0; } outputs:
0 0 0 0 I get the same results with Visual Studio 2015.
Why is this so? Is there a good reason that std::tuple POD types, not to mention a simple std::pair , cannot be trivially copied? I assume that their implementation provides some custom assignment operators, but how will they differ from the default versions generated by the compiler?
What pair fires before trivial copyability is due to the fact that the standard does not require copy / move assignment operations to be trivial. The standard explicitly states that copy / move constructors are defaults, but not so for assignments. An implementation may also use them, but the standard does not require this.
There is no really good reason why the standard does not require this. But this is not so.
For tuple things are much more complicated. Many tuple implementations are based on having the correct size / alignment storage buffer and using the new placement to create individual members in this buffer. This is all good and good, but this type should implement the manual copy / move constructor, since it must call the copy / move constructor of each type. Even if he knew that they are all trivially copied and copied via memcpy , that is still a manual operation. And this will disqualify him from trivial correspondence.
Now there are tuple implementations that can be trivially copied if types are trivially copied. But there is no need to apply them in this way. And this would greatly complicate tuple implementations in order to require them to implement themselves in one way, if all types can be trivially copied and otherwise implement them differently.
Since std::tuple has ctor copy / move and assign operations, it makes the class non-trivially copied.
See cpp link :
A trivially copied class is a class that
Has no non-trivial copy constructors (this also requires no virtual functions or virtual bases) Has no non-trivial move constructors Has no non-trivial copy assignment operators Has no non-trivial move assignment operators Has a trivial destructor
But std::tuple has all the above constructors and assignment operators.