#cpp #cpp11
С приходом C++11 в C++ были добавлены новые возможности и у меня появилось не понимание того, как возвращается список объектов из функции? Есть код: class SuperObject { SuperObject(int a_) : a(a_) { } private: int a = 0; }; std::listcollectSuperObjects() { std::list tmp; // do something with tmp return tmp; } Вопросы: Правильно ли понимаю, что компилятор не будет добавлять в SuperObject какие-либо конструкторы в нашем случае, т.к. пользователь написал свой? Как будет возвращаться результат функции collectSuperObjects? Прежде всего меня интересует ситуация с MSVC 2013.
Ответы
Ответ 1
1) Да, конструктора по умолчанию не будет, в С++03 было так же. 2) tmp возвращается перемещением, при этом элементы списка не копируются. (В С++03 тут было бы NRVO, но все равно нужен был бы копирующий конструктор). Для добавления элемента в список можно использовать tmp.emplace_back(1);.Ответ 2
В случае SuperObject будут сгенерированы конструкторы копирования и перемещения, а также соответствующие операторы копирования и перемещения. Никаких других конструкторов сгенерировано не будет. Чтобы компилятор прекратил генерировать копирующий конструктор, достаточно написать свой. Запретить генерацию перемещающего ещё проще, просто реализуйте что-либо из следующего списка: Конструктор копирования Конструктор перемещения Деструктор Оператор копирования Оператор перемещения Но почему такая разница с копирующим конструктором? Потому что старый код нужно поддерживать. Кстати, выше написана не вся правда про генерацию копирующего конструктора, в следующих случаях он будет автоматически сгенерирован как удалённый(= delete), если пользователь добавил: Конструктор перемещения Оператор перемещения Таким образом, стандарт почти уравнивает два конструктора, только деструктор пока не может запретить копирующий конструктор — это поломало бы очень много кода. Но это уже объявлено как deprecated, поэтому в будущем, конструктор копирования не будет генерироваться, если в классе будет деструктор или оператор копирования(пользовательский, я имею в виду): [depr.impldec] The implicit definition of a copy constructor as defaulted is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor. The implicit definition of a copy assignment operator as defaulted is deprecated if the class has a user-declared copy constructor or a user-declared destructor (12.4, 12.8). In a future revision of this International Standard, these implicit definitions could become deleted (8.4). Про 2 часть вопроса Abyx написал уже — будет либо NRVO, либо перемещение списка. Элементы перемещаться не будут.
Комментариев нет:
Отправить комментарий