Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::使_与std::初始值设定项_列表共享_C++_C++11_Std - Fatal编程技术网

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) );
}