Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ : how do I use type_traits to determine if a class is trivial?

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...

like image 603
kfmfe04 Avatar asked Oct 02 '11 05:10

kfmfe04


2 Answers

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.

like image 44
Nicol Bolas Avatar answered Oct 18 '22 20:10

Nicol Bolas


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.

like image 99
Luc Danton Avatar answered Oct 18 '22 19:10

Luc Danton