См. Should I use() or {} when forwarding arguments?. foo
- это клон std::vector
.Почему не существует перегрузки std :: initializer_list для std :: make_unique et al?
В N4140, unique.ptr.createstd::make_unique
определяется как так:
template <class T, class... Args> unique_ptr<T> make_unique(Args&&... args);
Замечания: Эта функция не будет участвовать в разрешении перегрузки, если
T
не является массивом.:
unique_ptr<T>(new T(std::forward<Args>(args)...))
.
Это означает, что реализации должны использовать ()
, а не {}
для инициализации объектов. В качестве примера, следующие
auto s1 = std::make_unique<foo>(3, 1).get()->size();
auto s2 = std::make_unique<foo>(1).get()->size();
auto s3 = std::make_unique<foo>(2).get()->size();
std::cout << s1 << s2 << s3;
выходы 312
тогда как если {}
(внутри std::make_unique
) был использован 211
бы выход. Поскольку списки инициализаторов не могут быть выведены, std::initializer_list
должен быть явно передан для получения последнего результата. Вопрос в том, почему не такая перегрузка, как это предусмотрено?
namespace test
{
template <class T, class Deduce>
std::unique_ptr<T> make_unique(std::initializer_list<Deduce> li)
{
return ::std::make_unique<T>(li);
}
};
int main()
{
auto p1 = test::make_unique<foo>({3, 1}).get()->size();
auto p2 = test::make_unique<foo>({1}).get()->size();
auto p3 = test::make_unique<foo>({2}).get()->size();
std::cout << p1 << p2 << p3;
}
Выходы 211
.
Я не считаю причины «вы можете написать сами» или «во избежание раздувания стандарта», чтобы быть очень вескими причинами. Есть ли недостатки в обеспечении этой перегрузки?
Я не думаю, что SFINAE необходимо. 'make_unique> (1, 73);' отлично работает, если я вывожу его из пространства имен и выполняю 'using namespace std;' (чтобы убедиться, что обе перегрузки видны). Если кто-то делает make_unique > ({1, 73}), это их вина. –
user6319825
@ пользователь6319825.Да, SFINAE не является существенным, компиляция терпит неудачу в любом случае, как раз по моему опыту, сообщения об ошибках в среде SFINAE «легче» диагностировать. – Niall
Еще. Они преднамеренно обсуждают «новый T (std :: forward (args) ...)», а не оставляют его до реализации, например [необязательно] (http://eel.is/c++draft/optional.object .ctor # 23): «Инициализирует содержащееся значение, как будто direct-non-list-initializing объект типа' T' с аргументами 'std :: forward (args)' .... »Это заставляет меня думать, что есть некоторое обсуждение * где-то * по крайней мере для 'make_unique' конкретно. –
user6319825