станд.:: список <станд.:: unique_ptr <T>>: раздавание его

Скажите, что у меня есть a std::list из class T:

std::list<T> l;

При передаче его в функции я использовал бы ссылку:

someFunction( std::list<T> &l )

Что лучший способ состоит в том, чтобы раздать (элементы) a std::list из unique_ptrs?

std::list< std::unique_ptr<T> >  l;

Как это:

someFunction( std::unique_ptr<T> ptr )

Или это:

someFunction( T* ptr )

Или это:

someFunction( T &ref )

И что, как был бы, я называю его с помощью std::list back() функция, например? Они - по моему скромному мнению, все "довольно" эквивалентные, но я уверен, что пропускаю что-то здесь.

Спасибо

8
задан rubenvb 11 July 2010 в 11:44
поделиться

2 ответа

От лучшего к худшему:

  1. someFunction (const T &);
  2. someFunction (T &);
  3. someFunction (const std :: unique_ptr &);
  4. someFunction (std :: unique_ptr &);

Первый вариант лучше всего, потому что он не изменяет объект, и он будет работать с объектом независимо от того, как вы его распределили (например, вы можете без проблем переключиться на shared_ptr).

Номер два также будет работать независимо от того, какой умный указатель вы используете; однако предполагается, что вы можете изменить объект, и всякий раз, когда вы можете сделать что-то const, вы должны это делать.

Номера 3 и 4 позволяют изменять объект, на который указывает указатель; однако № 3 не позволяет изменять интеллектуальный указатель, в то время как № 4 позволяет. У обоих есть недостаток, заключающийся в том, что они заставляют использовать unique_ptr, тогда как два вышеупомянутых будет работать независимо от класса интеллектуального указателя.

Передача unique_ptr по значению, как в некоторых других примерах, не является вариантом; unique_ptr должен быть уникальным. Если вы его копируете, подумайте об использовании shared_ptr.

Для первых двух, если вы вызвали его по результату back (), это выглядело бы так:

someFunction(*(lst.back()));  // dereference lst.back() before passing it in.

Для последних двух, если бы вы вызвали его по результату back (), это выглядело бы так:

someFunction(lst.back()); // pass the smart pointer, not the object to
                          // which the smart pointer currently points.
8
ответ дан 5 December 2019 в 18:56
поделиться

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

Это связано с тем, что unique_ptr не копируется, у него нет конструктора копирования типа unique_ptr :: unique_ptr (const unique_ptr & other) вместо этого он имеет только конструктор перемещения ( unique_ptr :: unique_ptr (unique_ptr && source) ).

1
ответ дан 5 December 2019 в 18:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: