std::make_shared deduces its second template parameter from the arguments to the function call. A braced-init-list is not an expression, and as such, has no type. Hence template argument deduction cannot deduce a type from it.
From §14.8.2.5/5 [temp.deduct.type]
The non-deduced contexts are:
— ...
— A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type. [ Example:
template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T
—end example ]
auto, however, is a special case that is allowed to deduce std::initializer_list<T> from a braced-init-list.
§7.1.6.4/7 [dcl.spec.auto]
... Otherwise, obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list, with std::initializer_list<U>. Deduce a value for U using the rules of template argument deduction from a function call (14.8.2.1), where P is a function template parameter type and the initializer is the corresponding argument. If the deduction fails, the declaration is ill-formed. Otherwise, the type deduced for the variable or return type is obtained by substituting the deduced U into P. [ Example:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
—end example ]
In your example, the variable list has the type initializer_list<shared_ptr<int>>, and when you pass it to make_shared, a vector can be constructed from it, which is then used to direct-initialize the A instance.
Other options are to construct a vector
auto res = std::make_shared<A>(std::vector<std::shared_ptr<int>>{x, y});
construct an A, which will then be moved
auto res = std::make_shared<A>(A{{x, y}});
or specify the template parameters for make_shared explicitly
auto res = std::make_shared<A, std::initializer_list<std::shared_ptr<int>>>({x, y});