Когда не поддерживается идиома копирования и свопинга

После прочтения этого об идиоме копирования и свопинга я прочитал this, который гласит: (2):

class_name & class_name :: operator= ( const class_name & )     (2)     

(2) Типичное объявление оператора присваивания копии, когда не может использоваться

Когда нам следует избегать использования идиомы копирования и свопинга?

И когда его "нельзя использовать" вообще?

Существуют ли случаи реальной жизни, когда неприменимы как "копирование и смена", так и правило "нуль"?

Я нашел этот question, но он был слишком специфичным и не содержал никаких указаний относительно того, как идентифицировать такие случаи.

Ответ 1

Когда следует избегать использования идиомы копирования и свопинга?

Когда вы можете доказать, что наивная копия безопасна и быстрее, чем swap.

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

И когда его "нельзя использовать" вообще?

Копировать-и-swap нельзя использовать, если тип не swappable.

Чтобы быть заменяемым, тип должен быть как конструктивным, так и переносимым, или вы должны определить функцию члена swap или функцию друга.

Ответ 2

Ваша ссылка, описывающая потенциальные реализации оператора присваивания, описываемого class_name& class_name::operator=(class_name) как:

Типичное объявление оператора присваивания копий при использовании идиомы копирования и свопинга

И class_name& class_name::operator=(const class_name&) как:

Типичное объявление оператора присваивания копии при невозможности использования идиомы копирования и свопинга

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

Итак, теперь вопрос в том, почему соглашение, упомянутое в http://www.cppreference.com?

Скажем, я реализую конструктор копирования для виртуального класса, и я хочу дать понять всем, кто унаследует, что они должны использовать идиому копирования и свопинга. Как мне это сделать? Я мог бы помочь им, выполнив для них копию при первом вызове:

class_name& class_name::operator=(class_name)

Это копия по значению, поэтому разработчик любых дочерних классов увидит, что я уже сделал копию для них, поэтому все, что им нужно сделать, это обмен.

Теперь, если бы у меня был class_name, в котором содержался член, который не мог быть скопирован, например, что, если мой класс имеет unique_ptr, так что он не может быть создан для копирования. Я могу указать, что, не делая аргумент copy по значению для оператора присваивания, например:

class_name& class_name::operator(const class_name&)

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