Сможет ли C ++ 11 unique_ptr и shared_ptr конвертировать в типы друг друга?

Предоставляет ли стандартная библиотека C ++ 11 какую-либо утилиту для преобразования изstd::shared_ptr вstd::unique_ptr, или наоборот? Это безопасная операция?

 curiousguy25 дек. 2016 г., 02:39
«STL» не означает стандартную библиотеку. STL не имеет ничего общего сshared_ptr.
 curiousguy25 дек. 2016 г., 02:41
@jaggedSpire Безопасность потоков будет означать, что ваши владельцы используются в разных потоках, т. е. счетчик использования не равен 1.
 jaggedSpire17 июн. 2016 г., 17:05
Определите "безопасную работу", пожалуйста. Какую безопасность вы ищете? безопасность управления жизненным циклом? Поток безопасности?
 jaggedSpire25 дек. 2016 г., 04:17
@curiousguy Я знал это. Моя точка зрения заключалась в том, что «безопасность» не была четко определена в вопросе ОП, и ему нужно было уточнить, какой тип «безопасности» он имел в виду, поскольку существует несколько видов.

Ответы на вопрос(2)

Решение Вопроса

std::unique_ptr Это способ выражения исключительной собственности в C ++ 11, но одна из его наиболее привлекательных особенностей заключается в том, что он легко и эффективно преобразуется вstd::shared_ptr.

Это ключевая часть того, почемуstd::unique_ptr так хорошо подходит как тип возврата фабричной функции. Фабричные функции не могут знать, захотят ли абоненты использовать семантику исключительного владения для объекта, который они возвращают, или является ли общее владение (т. Е.std::shared_ptr) было бы более уместным. Возвращаяstd::unique_ptrфабрики предоставляют вызывающим абонентам наиболее эффективный интеллектуальный указатель, но они не мешают вызывающим абонентам заменять его более гибким родственным элементом.

std::shared_ptr вstd::unique_ptr не допускается. После того, как вы перевели управление ресурсом ресурса наstd::shared_ptrнет никакого передума Даже если счетчик ссылок равен единице, вы не можете вернуть право собственности на ресурс, чтобы, скажем, иметьstd::unique_ptr Управляй этим.

Ссылка: Эффективный Современный C ++. 42 ОСОБЫЕ СПОСОБЫ УЛУЧШЕНИЯ ИСПОЛЬЗОВАНИЯ C ++ 11 и C ++ 14. Скотт Мейерс.

Короче говоря, вы можете легко и эффективно конвертироватьstd::unique_ptr вstd::shared_ptr но вы не можете конвертироватьstd::shared_ptr вstd::unique_ptr.

Например:

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);

или же:

std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");
 chema98909 мар. 2017 г., 21:22
@ Джейк Я добавил пример
 Jake08 нояб. 2016 г., 03:29
...Как ты делаешь это?

Дайте unique_ptr u_ptr, создайте shared_ptr s_ptr:

std::shared_ptr<whatever> s_ptr(u_ptr.release());

Идти другим путем нецелесообразно.

 Violet Giraffe16 авг. 2018 г., 15:04
@Eljay: спасибо, теперь я вижу!
 Zang MingJie19 авг. 2019 г., 10:56
@nmr Это небезопасно, потому что вы можете потерятьDeleter хранится внутриunique_ptr
 emlai25 дек. 2016 г., 02:55
Вот «правильный» путь:std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
 Zendel24 янв. 2019 г., 19:59
Инициализация в C ++ - это большой жирный беспорядок, и, наконец, он исправлен в C ++ 20. Мы все должны использовать новый единый способ. Увидеть:youtube.com/watch?v=9-_TLTdLGtc
 Stoica Mircea17 июл. 2018 г., 14:18
Преобразование @ nmr не является неправильным, просто немного не безопаснее, так что не отрицайте его ответ. Я считаю обращение Эмлая «правильным» способом.
 Violet Giraffe11 мар. 2018 г., 23:24
@polyvertex: есть ли реальная разница между этими двумя синтаксисами в данном конкретном случае?
 Eljay16 авг. 2018 г., 13:57
@VioletGiraffe • Я полагаю, что polyvertex выступает за использование нового синтаксиса списка инициализации - который избегает тихих сужающих преобразований и допускает инициализацию членов с единообразным синтаксисом - как хорошую привычку. Шесть из одного, полдюжины из другого?
 nmr17 июл. 2018 г., 22:56
Что менее безопасно в этом?
 polyvertex20 нояб. 2017 г., 18:06
И вот педантичный «правильный» путь:std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};

Ваш ответ на вопрос