Как объявить вектор unique_ptr как член класса данных? - PullRequest
8 голосов
/ 24 января 2012

Я хотел бы иметь вектор unique_ptr в качестве члена класса, который я создаю.

class Foo {
    [...]

private:
    vector<unique_ptr<Bar>> barList;
}

Но потом я начинаю получать загадочные сообщения об ошибках от VS2010 компилятор:

error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'

Наряду с несколькими ошибочными строками ниже той, которая погружается в реализацию Microsoft std::_Copy_impl<> ...

Я изменил объявление члена на

vector<unique_ptr<Bar>>* barList;

И это компилируется.Но я не могу не задаться вопросом, почему я не могу сделать это так, как я изначально хотел?Для ухмылок я попробовал это, и все отлично работает:

vector<Bar> barList;

Но теперь я теряю удобство unique_ptr.Я хочу свой торт, и я тоже хочу его съесть!

Ответы [ 5 ]

11 голосов
/ 24 января 2012

Проблема здесь в том, что где-то ваш код пытается вызвать оператор "copy-assignment" Foo.

Это заставляет компилятор попытаться сгенерировать оператор copy-assignment, который вызываетоператоры копирования-копирования всех подобъектов Foo.В конечном итоге это приводит к попытке скопировать unique_ptr, что невозможно.

5 голосов
/ 24 января 2012

unique_ptr не имеет семантики копирования, поэтому вы не можете использовать методы, которые бы копировали содержащийся объект.Вы можете сделать это со ссылками на rvalue, используя std::move в местах, где он пытается сделать копию.Не видя ваш код, я не могу сказать, где это будет.

Если он компилируется во второй форме, либо вы не выполняли тот же код, либо есть ошибка компилятора.Оба должны терпеть неудачу одинаково.

Ваш третий пример, хранение по значению является самым простым способом, если ваши объекты не являются большими и дорогими для хранения / копирования по значению.

3 голосов
/ 07 февраля 2014

Часто std::move(iUniquePtr) где-то отсутствует (например, при использовании push_back).

0 голосов
/ 29 мая 2014

Выдержки из www.cplusplus.com

std::unique_ptr::operator=

Назначение unique_ptr Объект приобретает право собственности на содержимое x, включая как сохраненный указатель, так и сохраненный удалитель (вместе с обязанностью удаленияобъект в какой-то момент).Любой объект, принадлежащий объекту unique_ptr до удаления вызова (как если бы был вызван деструктор unique_ptr).

Но также есть предупреждение:

Эта страница описываетфункция, представленная последней редакцией стандарта C ++ (2011).Старые компиляторы могут не поддерживать его.

MSVC 2010 определяет operator= как частный (не копируемый), но поддерживает метод swap.

0 голосов
/ 24 января 2012

Вы не можете использовать unique_ptr в векторе, потому что реализация вектора сильно зависит от оператора присваивания значений, который является закрытым в unique_ptr.Используйте shared_ptr из boost или другую интеллектуальную реализацию ptr из C ++ 11.

...