Ответ 1
В комментариях другого SO-ответа ОП разъясняет, что он здесь задает:
Я слышал, что разрешение на копирование CAN может произойти, даже если их больше 1 возвращения. Я хотел бы знать, когда исключение копии запрещено
Итак, я пытаюсь решить эту проблему здесь:
Элинирование операций копирования/перемещения (называемое копированием по стандарту С++) допускается при следующих обстоятельствах:
-
В выражении
return
в функции с типом возвращаемого класса, когда выражение является именем анонимного объекта с автоматической продолжительностью хранения (кроме параметра функции или переменной, введенной исключающим - объявление обработчика) с тем же типом (игнорируя cv-qualification) в качестве возвращаемого типа функции, операцию копирования/перемещения можно опустить, построив автоматический объект непосредственно в возвращаемое значение функции. -
В выражении throw, когда операндом является имя энергонезависимого автоматического объекта (отличного от параметра функции или параметра catch-clause), объем которого не выходит за пределы самого внутреннего окружения try- блок (если он есть), операция копирования/перемещения из операнда в объект исключения может быть опущена путем создания автоматического объекта непосредственно в объект исключения.
-
Когда объект временного класса, который не был привязан к ссылке, будет скопирован/перенесен в объект класса с тем же типом (игнорируя cv-квалификацию), операцию копирования/перемещения можно опустить, построив временный объект непосредственно в цель пропущенной копии/перемещения.
-
Когда объявление исключения обработчика исключений объявляет объект того же типа (кроме cv-qualification) в качестве объекта исключения, операцию копирования можно опустить, рассматривая объявление исключения как псевдоним для объект исключения, если значение программы не изменится, за исключением выполнения конструкторов и деструкторов для объекта, объявленного объявлением исключения. Не может быть перемещение из объекта исключения, поскольку оно всегда является lvalue.
Копирование разрешений запрещено во всех других случаях.
Число операторов возврата в функции не имеет никакого отношения к законности копирования. Однако компилятору разрешено не выполнять копирование, даже если оно является законным, по какой-либо причине вообще, включая количество операторов возврата.
С++ 17 Обновление
В настоящее время существует несколько мест, где копирование является обязательным. Если prvalue может быть привязано непосредственно к параметру функции по значению или по типу возвращаемого значения или к именованной локальной переменной, то копирование является обязательным в С++ 17. Это означает, что компилятор не должен беспокоиться даже о проверке копирования или перемещения конструктора. Legal С++ 17:
struct X
{
X() = default;
X(const X&) = delete;
X& operator=(const X&) = delete;
};
X
foo(X)
{
return X{};
}
int
main()
{
X x = foo(X{});
}