Предположим, что существует пространство имен 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;Ts? Было бы так плохо, если бы комиссия отказалась от своего создания, используяmake_unique?
Почему make_unique<T[N]> запрещен?