C++ std::使_与std::初始值设定项_列表共享
正如你在地图上看到的 错误:参数太多,无法运行 只有当我这样做()时,它才起作用: 有没有可能让C++ std::使_与std::初始值设定项_列表共享,c++,c++11,std,C++,C++11,Std,正如你在地图上看到的 错误:参数太多,无法运行 只有当我这样做()时,它才起作用: 有没有可能让std::make_shared接受它 提前感谢。原因是什么 auto example = new Derived({ { 0, std::make_shared<Base>() } }); 其中第一种类型为int,第二种类型为std::shared\u ptr。最后我们看到参数std::make_shared()被隐式转换为std::shared_ptr,我们可以开始了 在上面,我指出
std::make_shared
接受它
提前感谢。原因是什么
auto example = new Derived({ { 0, std::make_shared<Base>() } });
其中第一种类型
为int
,第二种类型
为std::shared\u ptr
。最后我们看到参数std::make_shared()
被隐式转换为std::shared_ptr
,我们可以开始了
在上面,我指出编译器通过寻找一个构造函数来处理初始值设定项列表,该构造函数要么直接接受初始值设定项列表,要么接受适当数量的参数,然后在必要时进行适当的隐式转换,将初始值设定项列表的元素传递给该构造函数。例如,在上面的示例中,编译器可以计算出您的std::shared_ptr
需要隐式转换为std::shared_ptr
,这仅仅是因为对的构造函数需要它
现在考虑
pair::pair (const first_type& a, const second_type& b);
std::共享({
{0,std::make_shared()}
})
问题在于make_shared
是一个部分专用的函数模板,可以接受任意数量和类型的参数。因此,编译器不知道如何处理初始值设定项列表
std::make_shared<Derived>({
{ 0, std::make_shared<Derived>() }
})
{{0,std::make_shared()}
在重载解析时,它不知道需要将其转换为std::initializer\u list
。此外,大括号的init列表永远不会通过模板推断而推断为std::initializer\u list
,所以即使您有
{{ 0, std::make_shared<Derived>() }}
std::使_共享({0,0})
而Derived
有一个合适的构造函数,它使用std::initializer\u list
,它仍然无法工作,原因相同:std::make\u shared
将无法为其参数推断任何类型
如何解决这个问题?不幸的是,我看不到任何简单的方法。但至少现在你应该知道为什么你写的东西不起作用了。为了让它起作用,你需要从列表创建一个自定义的
make\u shared\u,因为make\u shared
不支持非显式的初始值设定项列表。@brian很好地描述了原因
我将使用traits类将类型T
映射到初始值设定项列表的类型
std::make_shared<Derived>({0, 0})
templatestruct list_init{};//sfinae支持
模板结构列表_init{using type=std::pair;};
templateusing list_init_t=typename list_init::type;
模板
std::shared_ptr从_列表中生成_shared_(std::initializer_列表){
返回std::make_shared(std::move(list));
}
或者类似的
或者,将{…}
直接“强制转换”到初始值设定项列表
(不是强制转换,而是构造)可能会起作用
理论上,足够的反射元编程支持将允许shared\u ptr
在没有traits类的情况下完成这项工作,traits类是一个非常复杂的位。带括号的初始值设定项不是表达式,也没有类型。因此,make_shared
的模板类型推断无法进行推断。
{{ 0, std::make_shared<Derived>() }}
Derived::Derived(std::initializer_list<std::pair<int, std::shared_ptr<Base>>>) {}
{ 0, std::make_shared<Derived>() }
pair::pair (const first_type& a, const second_type& b);
std::make_shared<Derived>({
{ 0, std::make_shared<Derived>() }
})
{{ 0, std::make_shared<Derived>() }}
std::make_shared<Derived>({0, 0})
template<class>struct list_init{};// sfinae support
template<> struct list_init<Derived>{using type=std::pair<int, std::shared_ptr<Base>>;};
template<class T>using list_init_t=typename list_init<T>::type;
template<class T>
std::shared_ptr<T> make_shared_from_list( std::initializer_list<list_init_t<T>> list ){
return std::make_shared<T>( std::move(list) );
}