Страницы

Поиск по вопросам

воскресенье, 29 декабря 2019 г.

Как в новом C++11 возвращается список объектов хранящихся в std::list?

#cpp #cpp11


С приходом C++11 в C++ были добавлены новые возможности и у меня появилось не понимание
того, как возвращается список объектов из функции?

Есть код:

class SuperObject {
    SuperObject(int a_)
        : a(a_)
    {
    }

private:
    int a = 0;
};

std::list collectSuperObjects() {
    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, либо перемещение списка. Элементы перемещаться не будут.

Комментариев нет:

Отправить комментарий