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
и так далее.
поэтому я не знаю, зачем вам это нужно, если вы не пытаетесь проверить тривиальность конкретно.