Предположим, что существует пространство имен std
.
Проект комитета N3690 Комитета С++ 14 определяет std::make_unique
таким образом:
[n3690: 20.9.1.4]:
unique_ptr
создание [unique.ptr.create]
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
1 Примечания: Эта функция не должна участвовать в разрешении перегрузки, если
T
не является массивом.
2 Возвращает:unique_ptr<T>(new T(std::forward<Args>(args)...)).
template <class T> unique_ptr<T> make_unique(size_t n);
3 Примечания: Эта функция не должна участвовать в разрешении перегрузки, если
T
не является массивом неизвестной границы.
4 Возвращает:unique_ptr<T>(new typename remove_extent<T>::type[n]()).
template <class T, class... Args> unspecified make_unique(Args&&...) = delete;
5 Примечания: Эта функция не должна участвовать в разрешении перегрузки, если
T
не является массивом известной границы.
Теперь мне кажется, что это примерно так же ясно, как грязь, и я думаю, что для этого нужно больше изложения. Но этот редакционный комментарий в стороне, я считаю, что я расшифровал значения каждого варианта:
-
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
Стандарт вашего болота
make_unique
для типов без массива. Предположительно, "примечание" указывает, что некоторая форма статического утверждения или трюк SFINAE заключается в том, чтобы предотвратить успешное создание шаблона, когдаT
является типом массива.На высоком уровне см. это как смарт-указатель, эквивалентный
T* ptr = new T(args);
. -
template <class T> unique_ptr<T> make_unique(size_t n);
Вариант для типов массивов. Создает динамически выделенный массив
n
& times;Ts
и возвращает его вunique_ptr<T[]>
.На высоком уровне см. его как смарт-указатель, эквивалентный
T* ptr = new T[n];
. -
template <class T, class... Args> unspecified make_unique(Args&&...)
Недопустимое. "неуказанный", вероятно, будет
unique_ptr<T[N]>
.В противном случае был бы умным указателем, эквивалентным чем-то вроде недействительного
T[N]* ptr = new (keep_the_dimension_please) (the_dimension_is_constexpr) T[N];
.
Прежде всего, я прав? И если да, то что происходит с третьей функцией?
-
Если это запретит программистам пытаться динамически распределять массив, предоставляя аргументы конструктора для каждого элемента (так же, как
new int[5](args)
невозможно), то это уже покрывается тем фактом, что первая функция не может быть экземпляр для типов массивов, не так ли? -
Если это предотвратить, чтобы добавить к языку такой конструкции, как
T[N]* ptr = new T[N]
(гдеn
- некотораяconstexpr
), то, ну, почему? Было бы невозможно, чтобы существовалоunique_ptr<T[N]>
, которое обертывает динамически выделенный блокn
& times;T
s? Было бы так плохо, если бы комиссия отказалась от своего создания, используяmake_unique
?
Почему make_unique<T[N]>
запрещен?