Какие правила определяют, является ли объект тривиально копируемым

С введением c++11,тривиально copyableness стало довольно актуальным. Особенно в использовании "std:: atomic". Основы довольно просты. Класс foo тривиально копируется, если:

foo* src = new foo();
foo* dest = malloc(sizeof(foo));
memcpy(dest, src, sizeof(foo));

имеет тот же эффект, как:

foo* src = new foo();
foo* dest = new foo(src);

таким образом, объект, где копирование памяти будет иметь тот же эффект, что и конструктор копирования. Однако тут, конечно, есть подвох. Есть не только конструкторы копирования. Но также перемещайте конструкторы, перемещайте оператор присваивания. Так далее.

std:: is_trivially_copyable может использоваться для проверки того, является ли объект тривиально копируемым. Таким образом, методом проб и ошибок можно сделать объект тривиально копируемым.

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

1 ответов


наиболее четко определенный набор правил прямо из стандартного. Вот соответствующие записи из стандартного проекта N4296:

тривиально-копируемые типы определяются в [basic.типов/9

Cv-неквалифицированные скалярные типы, тривиально копируемые типы классов, массивы таких типов и энергонезависимые const-квалифицированные версии этих типов совместно называются тривиально копируемым типы.

тривиально-копируемые классы определяются в [класса]/6

тривиально копируемый класс-это класс, который: не имеет нетривиальных конструкторов копирования, не имеет нетривиальных конструкторов перемещения, не имеет нетривиальных операторов назначения копирования, не имеет нетривиальных операторов назначения перемещения и имеет тривиальный деструктор.

копировать / перемещать конструкторы в [класс.copy] / 12

копирование / перемещение конструктор для класса X является тривиальным, если он не является пользователем, параметр-тип-список эквивалентный параметр-тип-список неявным объявлением, а если класс X имеет виртуальных функций и виртуальных базовых классов, и класс X имеет не статические данные члены фитонциды-квалифицированный тип, и конструктор, выбранных для копирования/перемещения каждого прямого базового класса подобъекта является тривиальной, и для каждого нестатического элемента данных X, который имеет тип класса (или массив таковых)конструктор выбранный к копировать / перемещать этот элемент тривиален; в противном случае конструктор копирования/перемещения нетривиален.

копировать/перемещать операторы назначения в [класс.copy] / 25

оператор присваивания копирования/перемещения для класса X тривиален, если он не предоставлен пользователем, его список типов параметров эквивалентен списку типов параметров неявного объявления, и если класс X не имеет виртуальных функций и виртуальных базовых классов, А класс X не имеет нестатических членов данных volatile-квалифицированный тип, и оператор присваивания, выбранный для копирования / перемещения каждого прямого субобъекта базового класса, тривиален, и для каждого нестатического элемента данных X, который имеет тип класса (или его массив), оператор присваивания выбран для копирования / перемещения этого элемента; в противном случае оператор присваивания копирования/перемещения нетривиален.

деструкторы в [класс.dtor]/5

деструктор тривиален, если он не предоставлен пользователем и если: деструктор не является виртуальным, все прямые базовые классы своего класса имеют тривиальные деструкторы, для всех нестатических членов данных класса, которые имеют тип класса (или массив таковых), каждый такой класс имеет нетривиальный деструктор. В противном случае деструктор нетривиален.

пользовательские конструкторы в [dcl.fct.защита.по умолчанию]/5

явно-defaulted функции и неявно-объявленные функции вызываются совместно дефолт функции, и реализация должна содержать неявные определения для них (12.1 12.4, 12.8), что может означать определение их как исключенных. Функция предоставляется пользователем, если она объявлена пользователем и явно не по умолчанию или исключено в его первом заявлении. Функция, предоставленная пользователем явно по умолчанию (т. е. явно по умолчанию после первое объявление) определяется в точке, где оно явно по умолчанию; если такая функция неявно определена как удалить, программа плохо сформированные.

короткий ответ заключается в том, что короткий ответ иногда более полезен, чем длинный ответ.