C++: как использовать признаки типа для определения тривиальности класса?

В C++0x я хотел бы определить, является ли класс тривиальным/имеет стандартную компоновку, поэтому я могу использовать memcpy (), memset () и т. д...

как я должен реализовать код ниже, используя type_traits, чтобы я мог подтвердить, что тип тривиален?

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

Примечание: is_pod () слишком ограничен: я хотел бы, чтобы мой класс имел тривиальные конструкторы и т. д... ...для удобства.

добавлено: я думаю, std:: is_standard_layout может дать мне то, что я ищу. 1. Если я добавлю конструкторы, он по-прежнему возвращает true 2. Если я добавляю виртуальный метод, он возвращает false Это то, что мне нужно, чтобы определить, могу ли я использовать memcpy (), memset()

Edit: из объяснения Люка Дантона и ссылки ниже (уточнение):

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;
};

для memcpy (), чтобы быть счастливым:

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

таким образом, похоже, что is_trivial_class правильно: is_standard_layout не обязательно правильно...

2 ответов


на std::memcpy достаточно, чтобы тип был тривиально копируемым. Из n3290, 3.9 типы [basic.типы] пункт 2:

для любого объекта (кроме субобъекта базового класса) тривиально копируемого типа T, независимо от того, содержит ли объект допустимое значение типа T, базовые байты (1.7), составляющие объект, могут быть скопированы в массив char или unsigned char.

следующие абзацы также описывают другие полезные свойства тривиально типы copyables (т. е. не просто копирование к char массив).

std::is_trivially_copyable - это черта, чтобы обнаружить это. Однако на момент написания статьи он не реализован, например, GCC, поэтому вы можете использовать std::is_trivial как запасной вариант (так как, в свою очередь, требуется тривиальный конструктор копирования).

Я действительно не рекомендую использовать is_standard_layout, если вы действительно не знаете, что делаете (например, языковая совместимость на одной конкретной платформе), это не то, что вы хотите. больше информация о том, что тривиальность и стандартная компоновка, возможно, помогут вам указать точные требования, которые вы хотите.


определение POD в C++11:

структура POD - это класс без объединения, который является тривиальным классом и классом стандартной компоновки и не имеет нестатических членов данных типа non-POD struct, non-POD union (или массив таких типов).

поэтому, если вы не нарушаете правила стандартной компоновки или что-то в этом роде, is_pod должно быть достаточно. И если вы нарушаете правила стандартной компоновки, то вы не можете использовать memcpy и memset и так далее.

поэтому я не знаю, зачем вам это нужно, если вы не пытаетесь проверить тривиальность конкретно.