Компиляторы C++ автоматически генерируют конструкторы копирования и операторы присваивания копий. Почему бы и не swap
?Почему в C++ 0x нет созданных компилятором методов swap()?
В эти дни предпочтительный метод реализации оператора копирования-присваивания является копирования и замены идиомы:
T& operator=(const T& other)
{
T copy(other);
swap(copy);
return *this;
}
(ignoring the copy-elision-friendly form that uses pass-by-value).
Эта идиома имеет то преимущество, что она связана с транзакциями перед исключениями (при условии, что реализация swap
не выбрасывает). Напротив, созданный по умолчанию компилятор-оператор копирования-рекурсии рекурсивно выполняет копирование по всем базовым классам и членам данных и не имеет одинаковых гарантий безопасности исключений.
Между тем, внедрение swap
методов вручную является утомительным и подверженным ошибкам:
- Для того, чтобы
swap
не бросает, он должен быть реализован для всех, не являющихся членами POD в классе, так и в базовых классах, в их члены, не являющиеся членами POD, и т. д. - Если сопровождающий добавляет новый элемент данных в класс, сопровождающий должен помнить об изменении метода
swap
этого класса. В противном случае можно ввести тонкие ошибки. Кроме того, посколькуswap
является обычным методом, компиляторы (по крайней мере, я знаю) не выдают предупреждений, если реализацияswap
является неполной.
Не было бы лучше, если бы компилятор сгенерировал swap
методов автоматически? Тогда неявная реализация назначения копирования может использовать ее.
Очевидный ответ, вероятно, заключается в том, что идиома с копией и заменой не существовала, когда C++ был разработан, и теперь это может нарушить существующий код.
Тем не менее, может быть, люди могут отказаться в позволяя компилятору генерировать swap
используя тот же синтаксис, который использует C++ 0x для управления другими неявные функции:
void swap() = default;
и тогда может быть правила:
- Если существует метод
swap
, созданный компилятором, неявный оператор присваивания копий может быть реализован с использованием copy-and-swap. - Если не существует метода
swap
, созданного компилятором, неявный оператор присваивания копий будет реализован по-прежнему (вызов copy-assigment для всех базовых классов и для всех членов).
Кто-нибудь знает, были ли предложены такие (сумасшедшие?) Вещи в комитет по стандартам С ++, и если да, то какие члены комитета по мнениям?
Я задавался одно и то же количество.! раз, тем более, что 'swap' обычно реализуется в терминах' swapping' всех элементов данных в любом случае, так что это похоже на 'copy' или' assign' и новые версии 'move'. –
В C++ 0x' swap 'должно быть чем-то вроде строки' template void swap (T & x, T & y) {T temp (std :: move (x)); x = std :: move (y); y = std :: move (temp);} ', который по существу будет делать то, что сделают любые пользовательские функции свопинга. Я согласен с вашим вопросом, но пользовательские свопы больше не нужны, с введением ссылки на значения r-значения. 'std :: swap' будет работать отлично. –
GManNickG
Я подозреваю, что причина, по которой это не в C++ 98, заключается в том, что единственные генерируемые компилятором функции в C++ существуют, чтобы заставить классы вести себя как C-структуры: вы можете объявить их, уничтожить и скопировать. Как бы полезен «swap» по умолчанию или оператор '' по умолчанию '' (и оба могут быть реализованы с помощью полевых операций), стандарт C++ требовал минимальных функций по умолчанию, поэтому есть меньше, чтобы подавить, если вы этого не хотите , Синтаксис C++ 0x 'function = something' может быть намного лучше, поскольку он является необязательным. В принципе, у вас могут быть разные варианты безопасного и небезопасного обмена. –