In our last post, we learnt about the type trait std::is_trivial<T>. Today, let us go through another type trait that is quite similar.
The expression is_standard_layout<T>::value returns true if the layout of objects of type T is compiler independent, and hence is of standard format. Else, it returns false. This is important if we create objects in C++ and pass them to another language environment that is compatible with plain C structures. You might be aware that if we define a class with virtual functions, or one that derives from multiple base classes, the memory occupied by an object of that type is not guaranteed to have a standard structure. For example, it might be impossible to copy of objects such a type using the C function memcpy, as the elements might not be contiguous.
Let us look at various examples that use is_standard_layout<T> and finally conclude by identifying the difference between this and is_trivial<T>.
Example-1: Primitive Types
This trait can be applied to primitive types as well. Here is the example program:
And here is the output from the program:
Example-2: Simple Classes
Take a look at the structs A, B, C, and D below.
The struct A is a typical POD (Plain Old Data), containing only data members. Struct B includes a static member, but otherwise it is quite similar to A.
Struct C contains a no-arg constructor, a copy constructor, destructor, and a member function. Struct D is different in that it enforces access control.
Let us see the output of the program:
Notice that, even though D‘s members are not public, it still has a standard layout.
Example-3: Special Cases
Let us extend the earlier example by including two special cases:
1) Class has reference member variable
2) Class defines more than one access level
Here is the example:
Here is the program’s output:
As you can see, both the types have non-standard layout.
Example-4: Class Hierarchy
This section covers classes that have virtual functions or derive from other classes. Go through the example:
Struct G has a virtual destructor. We know that objects of such a class need additional storage for keeping track of the virtual table, something that is not the case with a simple struct acting like a POD.
Struct I uses private derivation while inheriting from C.
Struct J differs from H in that it defines an additional data member in its scope. Struct K inherits from two different base classes.
Can you guess the output? Here it is:
Interesting. Even though I derives privately from its base class, it has a standard layout.
The above examples show that there is substantial similarity between is_trivial<T> and is_standard_layout<T>. What is the difference, if any? Well, struct C in our example, holds the answer.
When we run this program, this is what we get:
The presence of constructors and destructor makes struct C non-trivial, although it has standard layout.
That is it for today. Hope you found the discussion useful.
Download the sources from here.
Have a nice weekend!
Recent Comments