Компиляторы С++ автоматически генерируют конструкторы копирования и операторы присваивания копий. Почему бы не swap
тоже?
В наши дни предпочтительным методом реализации оператора присваивания копирования является идиома копирования и свопинга:
T& operator=(const T& other)
{
T copy(other);
swap(copy);
return *this;
}
(игнорирование формы, упрощающей копирование, которая использует значение pass-by-value).
Эта идиома имеет преимущество в транзакции перед исключениями (при условии, что реализация swap
не выбрасывает). Напротив, созданный по умолчанию компилятор-оператор копирования-репликации рекурсивно выполняет копирование по всем базовым классам и членам данных и не имеет одинаковых гарантий безопасности исключений.
Между тем, внедрение методов swap
вручную является утомительным и подверженным ошибкам:
- Чтобы гарантировать, что
swap
не выбрасывает, он должен быть реализован для всех не-POD-элементов в классе и базовых классах, в их не-POD-элементах и т.д. - Если сопровождающий добавляет новый член данных в класс, сопровождающий должен помнить об изменении этого класса
swap
. В противном случае можно ввести тонкие ошибки. Кроме того, посколькуswap
является обычным методом, компиляторы (по крайней мере, я знаю) не выдают предупреждений, если реализацияswap
неполна.
Не было бы лучше, если бы компилятор автоматически сгенерировал методы swap
? Тогда неявная реализация назначения копирования может использовать ее.
Очевидный ответ, вероятно, таков: идиома "копирование и своп" не существовала, когда С++ был разработан, и теперь это может нарушить существующий код.
Тем не менее, возможно, люди могли бы сделать выбор, чтобы компилятор сгенерировал swap
с использованием того же синтаксиса, который использует С++ 0x для управления другими неявными функциями:
void swap() = default;
а затем могут быть правила:
- Если существует сгенерированный компилятором метод
swap
, неявный оператор присваивания копий может быть реализован с использованием copy-and-swap. - Если не существует метода
swap
, сгенерированного компилятором, неявный оператор присваивания копий будет реализован по-прежнему (вызов copy-assigment для всех базовых классов и для всех членов).
Кто-нибудь знает, были ли такие (сумасшедшие?) вещи предложены Комитету по стандартам C++, и если да, то какие члены комитета по мнениям имели?