std::make_shared
関数呼び出しの引数から 2 番目のテンプレート パラメーターを推定します。ブレース初期化リストは式ではないため、型はありません。したがって、テンプレート引数推定は、そこから型を推定できません。
§14.8.2.5 /5 [temp.deduct.type] より
— — 関連付けられた引数が初期化子リスト ( 8.5.4 ...
) である関数パラメーターですが、パラメーターがstd::initializer_list
おそらく cv 修飾されたstd::initializer_list
型を持っていないか、参照していません。【例:
template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T
—終わりの例]
auto
std::initializer_list<T>
ただし、波括弧初期化リストから推測できる特殊なケースです。
§7.1.6.4/7 [dcl.spec.auto]
...
P
T
auto
それ以外の場合は、 の出現箇所を新しく発明された型テンプレート パラメーター Uに置き換えるか、初期化子が波括弧初期化リストのstd::initializer_list<U>
U
場合はに置き換えることによってfromを取得します。関数呼び出し(14.8.2.1)からのテンプレート引数推定のルールを使用するための値をP
推定します。ここで、 は関数テンプレート パラメーターの型であり、初期化子は対応する引数です。控除が失敗した場合、宣言は不適切な形式です。U
それ以外の場合、変数または戻り値の型について推定された型は、推定された を に代入することによって取得されP
ます。【例:
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type
—終わりの例]
あなたの例では、変数list
のタイプinitializer_list<shared_ptr<int>>
は であり、それを に渡すと、それからmake_shared
avector
を構築できます。これは、A
インスタンスを直接初期化するために使用されます。
他のオプションは、vector
auto res = std::make_shared<A>(std::vector<std::shared_ptr<int>>{x, y});
を構築しA
、次に移動します
auto res = std::make_shared<A>(A{{x, y}});
または、テンプレート パラメータをmake_shared
明示的に指定します。
auto res = std::make_shared<A, std::initializer_list<std::shared_ptr<int>>>({x, y});