Различия между make_unique и make_shared при обработке массивов
С C++17 вы можете использовать make_unique
чтобы создавать умные указатели на массивы, такие как:
unique_ptr<int[]> ptr = make_unique<int[]>(10);
который создаст умный указатель на массив из 10 элементов (тот факт, что будет вызван надлежащий deleteter[], также хорош).
Однако в соответствии с этим make_shared
не поддерживает такую функциональность (по крайней мере, не в C++17, на мой взгляд):
shared_ptr<int[]> ptr = make_shared<int[]>(10);
приведенный выше код, очевидно, является незаконным. Действительно, моя Visual Studio 2017 (v141) выдает следующую ошибку:
C2070: 'int[]': illegal sizeof operand'
Интересно то, что shared_ptr
сам поддерживает типы массивов (т.е. shared_ptr<int[]>
законно), но make_shared
не. В то время как make_unique
делает.
Вопрос в том, что мешало стандартному производителю make_shared
поддержка типов массивов, как в случае с make_unique
?
1 ответ
Что мешало стандартным разработчикам позволить make_shared поддерживать типы массивов [...]?
Наверное, ничего, этот случай просто не рассматривался, аналогично std::make_unique
не присутствует в C++11, но добавлен в C++14. И, как указано в комментариях, этот недостающий кусок будет поставляться с C++20.
Есть разница между std::unique_ptr
а также std::shared_ptr
что упростило пренебрежение указателями необработанных массивов: пользовательские средства удаления являются частью std::unique_ptr
тип но не часть std::shared_ptr
тип. Таким образом, вы можете обрабатывать массив, как это
std::shared_ptr<int> array = std::shared_ptr<int>(new int[10],
[](int *ptr){ delete []ptr; });
и, следовательно, делегировать правильную очистку памяти в точку создания объекта. Это позволяет легко рассматривать необработанные массивы как особый случай std::shared_ptr
экземпляров.