Объекты, допускающие только перемещение, можно передавать функциям в качестве параметров и возвращать из функций, но если вы захотите переместить содержимое std::move() или оператором static_cast.
Спецификатор = delete можно задать для любой функции, а не только для копирующего конструктора и оператора присваивания. Тем самым вы ясно даете понять, что функция отсутствует. Но это еще не все — удаленная функция участвует в разрешении перегрузки, как любая другая, и вызывает ошибку компиляции, только если будет выбрана. Этим можно воспользоваться для исключения некоторых перегруженных вариантов. Например, если функция принимает параметр типа short, то сужение типа int можно предотвратить, написав перегруженный вариант, который принимает int, и объявив его удаленным:
void foo(short);
void foo(int) = delete;
Любую попытку вызвать foo с параметром типа int компилятор встретит в штыки, так что вызывающей программе придётся явно привести параметр к типу short:
foo(42); ←Ошибка, перегрузка для int удалена
foo((short)42); ←Правильно
А.3. Умалчиваемые функции
Если механизм удаленных функций позволяет явно объявить, что функция не реализована, то назначение умалчиваемых (defaulted) функций прямо противоположное - это средство указать, что компилятор должен автоматически сгенерировать реализацию функции «по умолчанию». Разумеется, это можно делать только для функций, которые компилятор и так генерирует: конструкторов, деструкторов, копирующих и перемещающих конструкторов, копирующих и перемещающих операторов присваивания.
Зачем это может понадобиться? Есть несколько причин.
•
•
•
•
•
•
Умалчиваемые функции объявляются путем добавления спецификатора = default, например:
class Y {
private:
Y() = default; ←Изменяем видимость
public:
Y(Y&) = default; ←Принимаем не-const ссылку
T& operator=(const Y&) = default;←┐объявляем умалчиваемой
│для документирования
protected:
virtual ~Y() = default; ←Изменяем видимость и добавляем virtual
};
Выше я упомянул, что сгенерированные компилятором функции обладают специальными свойствами, которые невозможно получить от версии, написанной пользователем. Самое существенное отличие заключается в том, что сгенерированная компилятором функция может быть
• Объекты с тривиальными копирующим конструктором, копирующим оператором присваивания и деструктором можно копировать с помощью memcpy или memmove.
• Литеральные типы, используемые в constexpr-функциях (см. раздел А.4) обязаны обладать тривиальными конструктором, копирующим конструктором и деструктором.