2016-03-09 3 views
0

У меня есть класс Whole, который содержит объект класса Part через unique_ptr. Поскольку я не предоставляю экземпляр-экземпляр для Whole, конструктор-копия удаляется из-за члена unique_ptr. Вот код:Оптимизация возвращаемого значения не работает для члена const unique_ptr?

class Part { 
}; 

class Whole { 
public: 
    Whole(std::unique_ptr<Part> part) : part(std::move(part)) { 
    } 
private: 
    const std::unique_ptr<Part> part; //yields error later! 
    //std::unique_ptr<Part> part; //ok! 
}; 

Я хотел бы создать целый экземпляр с помощью функции завод под названием сборки()

Whole build() { 
    auto part = std::unique_ptr<Part>{new Part{}}; 
    return Whole{std::move(part)}; 
} 

, которые я хочу использовать так:

int main() { 
    auto whole = build(); 
} 

Это работает до тех пор, пока unique_ptr для члена части Whole не объявлен const. Насколько я понимаю, это связано с оптимизацией возвращаемого значения, которая препятствует созданию и копированию временных рядов. Однако, , если я объявляю Whole :: part как const, мой компилятор жалуется, что вызывается удаленный экземпляр-конструктор. Почему невозможно использовать объявление const или есть проблема с этим кодом?

Я использую версию компилятора GNU: (Ubuntu 4.8.4-2ubuntu1 ~ 14.04.1) 4.8.4

+0

Копирование разрешений не является обязательным. – Lingxi

+1

Перемещение объекта изменяет существующий объект. И, отмечая элемент const, вы явно задали его как не изменяемый. –

+1

Возможно, вы хотели использовать 'std :: unique_ptr part; '? – juanchopanza

ответ

4

const std::unique_ptr Disallow двигаться конструктор класса Whole.

поэтому auto whole = build(); недействителен. (даже если вызов будет отменен, звонок должен быть действительным)

+0

Хорошо, это имеет смысл. Неправильная практика состоит в том, чтобы иметь элемент std :: unique_ptr и не предоставлять собственный конструктор копирования/перемещения и т. Д.? Кажется, что нужно помнить, что не объявляйте, а члены const таковы, что конструкция движения остается возможной. – user1304680

+0

Если у вас есть 'std :: unique_ptr', тогда конструктор копирования не сгенерирован (поскольку один из' std :: unique_ptr' удален), конструктор перемещения по-прежнему генерируется. Таким образом, класс правильно используется. Было бы более читаемым IMO явно запретить перемещение ('Whole (Whole &&) = default;') и удалить копию ('Whole (const Whole &) = delete;') (и то же самое для назначения). – Jarod42

Смежные вопросы