metalfox metalfox - 25 days ago 10
C++ Question

Type trait to identify types that can be read/written in binary form

Is there a type trait (or concept) to identify those types for which the following is safe?

template <typename T>
std::enable_if_t<std::some_type_trait<T>::value> Write(std::ostream &os,const T &x)
{ os.write(reinterpret_cast<const char *>(&x),sizeof(T)); }

template <typename T>
std::enable_if_t<std::some_type_trait<T>::value> Read(std::istream &is,T &x)
{ is.read(reinterpret_cast<char *>(&x),sizeof(T)); }


I’m thinking of classes containing POD excluding pointers (but not arrays). Something like
StandardLayoutType
s but without pointers. I neither want to constrain the objects to be
TrivialType
nor
TriviallyCopyable
.

Sorry if I’m inaccurate. I know very little of data representation.

Answer

Given a 1st parmeter of s, the read method:

Extracts characters and stores them into successive locations of the character array whose first element is pointed to by s

So your real question is: If I have initialized an object by writing a string of bytes to it's address, is it valid?

This is the concept of Value Representation. And the value representation of Trivially Copyable types is such that:

Copying the bytes occupied by the object in the storage is sufficient to produce another object with the same value

Thus you want to ensure that your object is Trivially Copyable this isn't per say a standard concept but it can be succinctly defined as:

The spirit of the assertion that at least one Trivial initializer exists for the object boils down to these requirements of a Trivially Copyable type, it's non-static members, and any of it's base classes:

  1. It's given Trivial Initializer is, or behaves as, the corresponding default intializer
  2. It has no virtual methods
  3. It has no members of a volatile-qualified type

As far as the requirement of a Trivial destructor:

  • The destructor is not user-provided (meaning, it is either implicitly declared, or explicitly defined as defaulted on its first declaration)
  • The destructor is not virtual (that is, the base class destructor is not virtual)
  • All direct base classes have trivial destructors
  • All non-static data members of class type (or array of class type) have trivial destructors

Having fully defined what it means to be a Trivially Copyable type, it is impossible for a "type trait or concept" to determine whether all of these requirements are met in all cases, for example: A type that defines a Trivial Initializer with a signature that matches the default initializer may or may not be Trivially Copyable contingent on the code which initializes the type in that intializers body; For such a type, the only way to determine if it's Trivially Copyable is human inspection of the intializer.

Having thus correctly defined what you're looking for I will suggest that if you are willing to tighten the requirements I'd suggest that the closest type trait which will guarantee a Trivially Copyable type is: is_trivial

Comments