2

std::is_trival<T>::value can determine if class T is trivial. However, I cannot think of a scenario that needs this information.

Are there any examples?

Some thoughts of mine:

Provided that class T is trivial, does it mean T can be safely copied by memcpy like this:

T t1, t2;
memcpy(&t1, &t2, sizeof(T));

?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • 1
    Take a look at [What are Aggregates and PODs and how/why are they special?](http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821) – BigBoss Feb 20 '13 at 16:30
  • i would search the standard for "trivial" and check what explanation involves that concept. off-hand i can't think of any particular use, since trivial copying is a more basic feature. but, check it out. – Cheers and hth. - Alf Feb 20 '13 at 16:33

2 Answers2

6

If a type is trivial it can, for example, be copied with memcpy. That's a requirement for user-defined types that are used as arguments to the std::atomic template. That is, for a user-defined type T, atomic<T> is allowed (and, for larger types, required) to implement assignment from an object of type T to an object of type atomic<T> with memcpy. Similarly, testing for equality, when needed, is done with memcmp.

The reason for using these C functions instead of the C++ operators is so that atomic operations do not make any calls into user code. Doing that could lead to mysterious deadlocks from innocent-looking code.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • 3
    Another thing is, trivial types don't need to have their destructor called, which may increase efficiency for, say, a `std::vector`. So it's not only safety, but also plain efficiency. – Xeo Feb 20 '13 at 17:32
  • @Xeo - true, but I don't think that responds to the question that was asked, which was "when do I need to know this"? Hmm, come to think of it, mine doesn't answer that, either: chances are that if you're defining an atomic type, you know that your type is trivial, and don't need a type trait to tell you that. – Pete Becker Feb 20 '13 at 17:41
  • 1
    I think it answers it nicely - "when do I need to know this?" - "when you want to write code as performant as possible" and "when special requirements make non-trivial types a no-go". You *could* say it's (like many parts of C++) only really useful for library writers, but eh... – Xeo Feb 20 '13 at 18:08
  • Comparing trivial types with `std::memcmp()` is only allowed where spurious non-equality is acceptable. It happens due to non-canonical representations, as an example look into floating-point and padding. – Deduplicator Mar 25 '18 at 11:28
0

Really, trivial types are useful with /anything/ which just takes a character pointer and a length. Pete Becker's answer describes the important case, but here's something silly: you can serialize a trivial type using std::ostream::write, and read it back using std::istream::read.

template<typename T>
std::enable_if<std::is_trivial<T>, void> 
bin_write(std::ostream& out, const T& data) {
  out.write(reinterpret_cast<const char*>(&data), sizeof(T));
}

template<typename T>
std::enable_if<std::is_trivial<T>::value, T> 
bin_read(std::istream& in) {
  using T_in = std::remove_cv_t<T>; //even if T is const, the buffer can't be
  T_ buffer;
  in.read(reinterpret_cast<char*>(&buffer), sizeof(T_));
  return buffer;
}

Obviously you can't use this on raw pointers (or raw pointer wrappers e.g. std::experimental::observer_ptr). And this ignores endianness so you might not want to send this data to other applications on other computers. But it's useful if you want to write simulation restart files, for instance, or if you need to transfer data between GCC compiled C++ and GCC compiled Fortran.

hegel5000
  • 876
  • 1
  • 7
  • 13
  • Just to clarify: Fortran is a bit older and doesn't have nearly the same level of standardization as C or C++, so you have fewer guarantees with serialization and deserialization in the Fortran standard library or its builtin operators. The result is that features in C++ like std::is_trivial, and all the guarantees in the standard surrounding that, are absolutely divine. – hegel5000 Apr 10 '18 at 12:38