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.