10

In C++0x, I would like to determine if a class is trivial/has standard layout so I can use memcpy(), memset(), etc...

How should I implement the code below, using type_traits, so I can confirm that a type is trivial?

template< typename T >
bool isTrivialType()
{
  bool isTrivial = ???
  return isTrivial;
}

NOTE: is_pod() is too restrictive: I would like my class to have trivial constructors, etc... ...for convenience.

Added: I think std::is_standard_layout<> may give me what I'm looking for. 1. If I add constructors, it still returns true 2. If I add a virtual method, it returns false This is what I need to determine if I can use memcpy(), memset()

Edit: From Luc Danton's explanation and link below (clarification):

struct N { // neither trivial nor standard-layout
   int i;
   int j;
    virtual ~N();
};

struct T { // trivial but not standard-layout
    int i;
private:
    int j;
};

struct SL { // standard-layout but not trivial
    int i;
    int j;
    ~SL();
};

struct POD { // both trivial and standard-layout
    int i;
    int j;
};

For memcpy() to be happy:

// N -> false
// T -> true
// SL -> ??? (if there are pointer members in destructor, we are in trouble)
// POD -> true

So it does look like is_trivial_class<> is correct: is_standard_layout<> is not necessarily right...

Jonas
  • 121,568
  • 97
  • 310
  • 388
kfmfe04
  • 14,936
  • 14
  • 74
  • 140
  • it looks like the newly added std::is_standard_layout<> may do what I want - unlike POD, I can add constructors and it will still return true – kfmfe04 Oct 02 '11 at 06:06
  • 1
    Standard Layout is not quite right; `std::vector` may well be standard layout, for instance, but using `memcpy` would be a bad idea nonetheless. – Dennis Zickefoose Oct 02 '11 at 07:27

2 Answers2

7

For std::memcpy it is sufficient that the type be trivially copyable. From n3290, 3.9 Types [basic.types] paragraph 2:

For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.

Following paragraphs also describe other useful properties of trivially copyables types (i.e. not just copying to a char array).

std::is_trivially_copyable is the trait to detect just that. However as of my writing it's not implemented by e.g. GCC, so you may want to use std::is_trivial as a fallback (since in turn it requires a trivial copy constructor).

I really do not recommend using is_standard_layout, unless you really know what you're doing (e.g. language interoperability on one particular platform) it's not what you want. More information on what triviality and standard layout is about to perhaps help you specify the exact requirements you want.

Community
  • 1
  • 1
Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • thank you, Luc - after investigating though your like, I think you have the best answer - ty for advising the use of std::is_trivial as a fallback for gcc! I will alias is_trivially_copyable to is_trivial until gcc implements it - that way, I can update my code in one spot. – kfmfe04 Oct 02 '11 at 09:06
1

The definition of POD in C++11 is:

A POD struct is a non-union class that is both a trivial class and a standard-layout class, and has no non-static data members of type non-POD struct, non-POD union (or array of such types).

So unless you are violating the rules of standard layout or something of that nature, is_pod should be sufficient. And if you're breaking the rules of standard layout, then you can't use memcpy and memset and so forth.

So I don't know why you need this unless you trying to test triviality specifically.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    A POD is more than sufficient to satisfy standard layout. However, it is too restrictive. For instance, if I add a constructor, even one that just trivially sets a member, it is no longer POD, but technically, if I understand correctly, it still has standard layout (ie, I can safely memcpy and memset). Therein lies the problem: POD appears to be too restrictive for my needs. – kfmfe04 Oct 02 '11 at 05:43