Различия между 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 экземпляров.

Другие вопросы по тегам