Ответ 1
Резюме:
Для С++ 11 я бы включил:
- move-ctor (noexcept)
- move-assign (noexcept)
- общий порядок (оператор <() для натурального общего порядка и std:: меньше < > если естественный общий порядок не существует).
- хэш < >
И удалит:
- swap() (non-throwing) - заменяется операциями перемещения.
Комментарий
Алекс пересматривает концепцию обычного типа в Элементах программирования. Фактически, большая часть книги посвящена регулярным типам.
Существует набор процедур, включение которых в вычислительную базис типа позволяет помещать объекты в структуры данных и использовать алгоритмы для копирования объектов из одной структуры данных в другую. Мы называем типы, имеющие такой базисный регулярный, поскольку их использование гарантирует регулярность поведения и, следовательно, интероперабельность. Раздел 1.5 EoP
В EoP Алекс вводит понятие basic_type, которое дает нам алгоритм замены без метания, который можно использовать для перемещения. Шаблон basic_type не реализуется на С++ в любом особенно полезном mannor, но вы можете использовать не-throwing (noexcept) move-ctor и move-assign как разумные аппроксимации (базовый тип позволяет перемещаться в/из временного без дополнительного уничтожения для временного). В С++ 03 обеспечение не-бросания swap() было рекомендуемым способом аппроксимировать операцию перемещения, если вы предоставили move-ctor и move-assign, тогда будет использоваться стандартная std:: swap() (хотя вы все равно можете реализовать более эффективный).
[Я в записи, рекомендуя использовать один оператор присваивания, передавая его по значению, для покрытия как назначения назначения, так и назначения копирования. К сожалению, текущие языковые правила для того, когда тип получает по умолчанию move-ctor, заставляет это сломаться с составными типами. Пока это не будет исправлено на языке, вам нужно будет написать два оператора присваивания. Тем не менее, вы все равно можете использовать pass by value для других аргументов приемника, чтобы избежать комбинаторики при обработке move/copy для всех аргументов. ]
Алекс также добавляет требование полного упорядочения (хотя, возможно, не существует естественного общего порядка, и порядок может быть чисто репрезентативным). оператор <() должен быть зарезервирован для естественного общего упорядочения. Мое предложение состоит в том, чтобы специализировать std:: less < > (), если естественное полное упорядочение недоступно, есть прецедент для этого в стандарте).
В EoP Alex расслабляет требования к равенству, чтобы обеспечить достаточное представительное равенство. Полезное уточнение.
Регулярный тип также должен быть эквационально полным (то есть оператор ==() должен быть реализован как функция, отличная от друга, не являющейся членом). Тип, который является эквационально полным, также сериализуем (хотя и без канонического формата сериализации, реализация потоковых операторов малопригодна, за исключением отладки). Тип, который является эквационально полным, также может быть хэширован. В С++ 11 (или с TR1) вы должны указать специализацию std:: hash.
Другим свойством регулярных типов является area(), для которого еще нет стандартного синтаксиса - и, вероятно, мало оснований для фактического внедрения, кроме тестирования. Это полезная концепция для определения сложности - и я часто реализую ее (или приближение) для сложности тестирования. Например, мы определяем сложность копии, ограниченную временем, чтобы скопировать область объекта.
Понятие регулярного типа не зависит от языка. Одна из первых вещей, которые я делаю при представлении нового языка, - это то, как обычные типы проявляются на этом языке.