Исправляем косяк std::shared_ptr с массивами



Ну не мы сами, конечно. Стандарт С++17 исправляет этот момент.



Что мы теперь имеем.



Для создания объекта таким конструктором:



template< class T >   

explicit shared_ptr( T* ptr );




используется делитер delete ptr, если T - не массив, и delete[] ptr если Т -массив.



Также теперь изменился тип хранимого объекта element_type. Раньше был просто шаблонный тип Т, теперь же это



using element_type = remove_extent_t<T>;




std::remove_extent - это такой type_trait. Все, что нужно о нем знать - если Т - массив, то тип element_type будет совпадать с типом элементов массива.



Теперь мы даже можем использовать operator[] для доступа к элементам массива. Делается это так:



std::shared_ptr<int[]> num(new int[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9});

for (std::size_t i = 0; i < 10; ++i)

std::cout << num[i] << ' ';




Так что теперь это действительно полноценные шареные массивы из коробки. Весь интерфейс подогнали под это дело.



Но вот вопрос: а нафига это вообще надо? Когда кто-то вообще в последний раз использовал динамический массив?



Мы же вроде на плюсах пишем. Есть плюсовые решения - std::vector, если размер не известен на момент компиляции, и std::array, если известен. У них и интерфейс удобный и унифицированный и все-таки это объектно-ориентированный подход. И сердцу тепло, и глаз радуется. Динамические массивы выглядят, как окаменелые какашки динозавров.



C std::array соглашусь. Думаю, что нет адекватных оправданий использования динамических и статических массивов, длина которых известна в compile-time. std::array - очень простая и тонкая обертка над статическим массивом и ее использование вырождается компилятором до использования массива.



Но вот с векторами немного сложнее. Удобство требует жертв. Именно в плане производительности. Поэтому в узких бутылочных горлышках, где надо выжимать всю скорость из кода, лучше использовать динамические массивы вместо std::vector. Видел запрос от Захара на пример, который подверждает эту мысль. Отвечу на него в другом посте как-нибудь. Но обычному бэкэндеру, думаю, это сильно не пригодится.



Если фича есть, значит она кому-то нужна. Просто иногда интересно узнать о таких минорных изменениях. А кому-то поможет больше не использовать кастомные делитеры и иметь более понятный код.



Fix your flaws. Stay cool.



#cpp17 #memory