Подтвердить что ты не робот

Использование T [] в качестве параметра шаблона

Я недавно наткнулся на использование unique_ptr<T[]>, где я понимаю, что цель состоит в том, чтобы удалить указатель с помощью delete[].

Меня озадачивает то, что unique_ptr<T[3]> вместо этого недействителен (исправьте меня, если я ошибаюсь).

Каков тип T [] в шаблоне? Чем он отличается от T [3]? Это массивы, так что разве они не должны быть одинаковыми? Есть ли другое использование T [] в качестве типа в шаблонах?

4b9b3361

Ответ 1

T[] - это тип. Это тип "массив неизвестной границы T". Это неполный тип.

T[3] также является типом. Это тип "массив из 3 T". Это другой тип от T[], так же как int и double - разные типы.

Шаблон default_delete частично специализирован для неполных массивов формы T[]. Тем не менее, типы полного массива, такие как T[3], запрещены, так как это было бы очень запутанным: unique_ptr не может определить, сколько времени занимает ваш массив, поскольку он обрабатывает массив только через указатель на его первый элемент.

(В механике есть технические подробности: специализация default_delete<T[3]> не запрещена активно, но поскольку ее оператор вызова ожидает T(*)[3], он, как правило, не соответствует указателю, который поступает из unique_ptr, и даже если вызов был хорошо сформирован, выражение delete на таком указателе не допускается (= имеет поведение undefined). Вы "не можете удалить массивы", если хотите, вы можете только "удалить [] массивы по размеру -установленные указатели".)

Обратите внимание, что шаблон функции make_unique активно удаляется для полных типов массивов.

Любопытно, что для make_shared комитет пошел по другому маршруту и ​​разрешил полные типы массивов. Для этого shared_ptr<T[N]> имеет предварительное условие, что вы строите его только из сопоставленного new T[N] (хотя это вообще не проверяемо). (Я никогда не понимал, почему это была хорошая идея.)