Bil*_*ias 5 c++ vector initializer-list make-shared list-initialization
我错过了一些东西std::make_shared。它不能解决 a 的类型std::initializer_list,还是我做错了什么?
#include <vector>
#include <memory>
class A {};
int main()
{
A a;
std::vector<A> veca{A(), A{}, a}; // this works ofc
std::vector<A> vecb({A(), A{}, a}); // this too
std::make_shared<std::vector<A>>(vecb); // and this, ofc
std::make_shared<std::vector<A>>({a}); // what's wrong here?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误:
main.cpp:21:41: error: too many arguments to function ‘std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = std::vector; _Args = {}]’
std::make_shared<std::vector<A>>({a});
^
In file included from /usr/include/c++/6/memory:82:0,
from main.cpp:10:
/usr/include/c++/6/bits/shared_ptr.h:632:5: note: declared here
make_shared(_Args&&... __args)
^~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
考虑以下您的问题的最小示例:
\ntemplate <typename... Ts>\nvoid f(Ts&&...); // replacement for std::make_shared\n\nint main()\n{ \n f({1});\n}\nRun Code Online (Sandbox Code Playgroud)\n这种情况在 C++ 标准中的[temp.deduct.call/1]中进行了描述:
\n\n\n模板参数推导是通过将包含参与模板参数推导的模板参数的每个函数模板参数类型(称为
\nP)与调用的相应参数类型(称为A)进行比较来完成的,如下所述。P如果从Gives\nstd::initializer_list<P\xe2\x80\xb2>或P\xe2\x80\xb2[N]for someP\xe2\x80\xb2and中删除引用和 cv 限定符N,并且参数是非空初始值设定项列表 ([dcl.init.list]),则对初始值设定项列表的每个元素独立执行推导,取P\xe2\x80\xb2作为单独的函数模板参数类型P\xe2\x80\xb2i和i第一个初始化元素作为相应的参数。在这种P\xe2\x80\xb2[N]情况下,如果N是非类型模板参数,N则从初始值设定项列表的长度推导出来。否则,初始值设定项列表参数会导致该参数被视为非推导上下文([temp.deduct.type])。
对于您的情况,最后一句话适用。有趣的是,错误消息显示了 GCC 的其他内容,这很奇怪。使用 Clang,错误消息很清楚:
\n\n\n\n
error: no matching function for call to \'f\'\n
note: candidate template ignored: substitution failure: deduced incomplete pack <(no value)> for template parameter \'Ts\'