единственная разумная версия - первая, которую вы предложили.
Если вы посмотрите на std::shared_ptr documentation, вы увидите, что нет конструктора, который получает аргументы конструктора управляемых объектов в качестве вариационного шаблона. означает, что вы не найдете Somthing как:
template<class T,class... Arg>
std::shared_ptr<T>::shared_ptr(Args&&... args)
так вы не можете действительно сделать Somthing как
std::shared_ptr<std::string> p("hi there");
это не будет работать. , что вы можете сделать для std::shared_ptr
строит его T*
, так что это должно работать:
std::shared_ptr<std::string> p(new std::string("hi"));
сейчас, вы можете подумать: «Эй, я могу использовать его внутри инициализатора-лист!» но нет, это:
std::initializer_list<std::shared_ptr<std::string>> il{
new std::string("hi there"),
new std::string("hi there")
};
не будет работать, потому что конкретные costructor имеют явное ключевое слово на нем, поэтому он должен быть явно объявлены!
так в конце концов, вы можете написать что-то вроде
std::initializer_list<std::shared_ptr<std::string>> il{
std::shared_ptr<std::string>(new std::string("hi there"))
};
но, как вы видите себя, ваша первая попытка гораздо проще и короче.
summery: учитывая тот факт, что конструктор shared_ptr отсутствует, который передает аргументы в конструктор manged object, вы не можете использовать {args ...} как допустимый синтаксис. учитывая, что shared_ptr, который получает T*
, должен быть явно указан, вы не можете сделать что-то вроде {new T (args ..)}, поэтому самым простым способом является использование std::make_shared
.
пс. в вас первый фрагмент, вещь, которая используется для инициализации вектора : список инициализаторов. только то, что это тип std::initializer_list<std::shared_ptr<Foo>>
, а не std::initializer_list<Foo>
, как второй фрагмент.