Компилятор выполняет оптимизацию возвращаемого значения в случае возврата переменной-члена?

Учитывая следующий код

class foo
{
    private:
        boost::shared_ptr <std::deque<foo> > m_ptr;
    public:
        foo();
        boost::shared_ptr <std::deque<foo> > get_my_ptr()
        {
            return m_ptr;
        }
};

И когда мы позвоним get_my_ptr() функционировать так

boost::shared_ptr <std::deque<foo> > ptr = get_my_ptr()

Вызывает ли компилятор конструктор копирования для создания объекта ptr или он может выполнять nrvo? И какая разница мы называем это так

const boost::shared_ptr <std::deque<foo> >& ptr = get_my_ptr()

2 ответа

Решение

При использовании NRVO компилятору разрешается опускать конструкции копирования и перемещения, если выражением оператора возврата является имя локального энергонезависимого объекта с автоматической продолжительностью хранения, который не является параметром функции. Этот локальный объект создается непосредственно в хранилище, куда в противном случае было бы скопировано возвращаемое значение функции. Эти условия не выполняются для переменных-членов. Это возможно только в том случае, если вы создали локальную копию участника:

boost::shared_ptr<std::deque<foo>> get_my_ptr()
{
    auto p = m_ptr;
    return p;
}

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

Компиляция не должна выполнять RVO, когда возвращается переменная-член. Если это так, объект останется с недопустимым членом.

Другие вопросы по тегам