6

In addition to std::is_trivial and std::is_trivially_copyable, C++11 provides a number of type traits for checking whether types have trivial constructors, destructors and copy/move assignment operators, i.e:

  • std::is_trivially_constructible
  • std::is_trivially_default_constructible
  • std::is_trivially_copy_constructible
  • std::is_trivially_move_constructible
  • std::is_trivially_assignable
  • std::is_trivially_copy_assignable
  • std::is_trivially_move_assignable
  • std::is_trivially_destructible

What is their original intended purpose? Surely some C++ committee paper(s) must explain the rationale for their inclusion in the C++ standard library.

jotik
  • 17,044
  • 13
  • 58
  • 123
  • They are great to have in a unit test to see if someone messed up and made something that MUST be trivially_whatever not trivial leading to a silent invocation of undefined behaviour in the production code. Also make nice `static_assert` compile-time traps in the production code in case someone is being *really* stupid and not unit testing. – user4581301 Feb 20 '17 at 21:01

1 Answers1

2

Why are they in the standard library? Because they're useful but impossible to implement in the language.


Two specific examples of usefulness.

  • std::is_trivially_copy_constructible - If I have a vector of a type that is trivially copy constructible, I don't need to individually copy every element when I do a reallocation. I can memcpy() the whole block in one go. We need this type trait to check when this optimization is safe.
  • std::is_trivially_destructible - Trivial destruction is an important quality of a type. It's one of the criteria for it to be a literal type and thus usable in a constant expression. There are situations where I might want my type to be usable as a literal type where it is possible for that to happen (e.g. std::optional). We need this type trait in order to make optional<T> conditionally trivially destructible.
Community
  • 1
  • 1
Barry
  • 286,269
  • 29
  • 621
  • 977
  • 5
    "If I have a vector of a type that is trivially copy constructible, I don't need to individually copy every element when I do a reallocation." That requires trivially copyable. – T.C. Feb 21 '17 at 02:08
  • 1
    I have read that memcpy can be much less efficient than using the trivial copy constructor because the compiler generate instructions that copies whole large block of memory, while memcpy copy byte by bytes... So the good news is just not to take care about this property of types, (modern) compiler will do a better job if you do not use it. – Oliv Feb 21 '17 at 07:57
  • @Oliv Why do you think the compiler can generate efficient code for copying a bunch of objects, but not a bunch of bytes? – Barry Feb 21 '17 at 14:44
  • @Barry Because the *value representation* of a type does not always match the *object representation* of that type ([basic.types/4](http://eel.is/c++draft/basic.types#4)). – jotik Feb 21 '17 at 17:23