Вот случаи, когда допустимое значение копии разрешено (class.copy / 31):
в операторе возврата в функции с возвратом класса тип, когда выражение является именем энергонезависимого автоматического объекта c (отличного от параметра функции или оператора catch) с тем же типом cv-unqually, что и тип возвращаемого функцией, операция копирования / перемещения может быть опущена путем создания объекта автомати c непосредственно в возвращаемое значение функции
в выражении броска, когда операндом является имя энергонезависимого объекта автомата c (другое чем параметр функции или предложения catch), область действия которого не выходит за пределы самого внутреннего охватывающего блока try (если он есть), операция копирования / перемещения из операнда в объект исключения (15.1) может быть опущена построение объекта c automati непосредственно в объекте исключения
- , когда временный объект класса не был связан со ссылкой (1 2.2) будет скопирован / перемещен в объект класса с тем же cv-неквалифицированным типом, операция копирования / перемещения может быть опущена путем создания временного объекта непосредственно в цель пропущенного копирования / перемещения
- , когда Объявление-исключение обработчика исключений (раздел 15) объявляет объект того же типа (за исключением cv-квалификации), что и объект исключения (15.1), операция копирования / перемещения может быть опущена
Ничто из этого не верно для вашего примера (мы не находимся в выражении возврата, выражении броска или объявлении исключения. И в вашем примере вообще нет временных значений.), Поэтому копирование происходит каждый раз, когда вы ожидаете, что это произойдет.
Обратите внимание, что допустимое значение копирования разрешено в упомянутых случаях, но не обязательно , Таким образом, даже в этих случаях компилятору разрешено выдавать копии (это верно для C ++ 11. В C ++ 17 есть некоторые случаи, когда исключение копий является обязательным. Но ни один из ваших примеров не допускает elision в C ++ 17 тоже.)