std :: make_shared和std :: initializer_list [英] std::make_shared with std::initializer_list
问题描述
#include <iostream>
#include <memory>
class Base
{
public:
Base() {}
};
class Derived : public Base
{
public:
Derived() {}
Derived(std::initializer_list<std::pair<int, std::shared_ptr<Base>>>) {}
};
int main(int argc, char ** argv)
{
auto example = new Derived({
{ 0, std::make_shared<Derived>() }
});
return 0;
}
它可以使用( std :: make_shared 和 std :: initializer_list
作为参数我遇到错误:
It works (live preview) normally, but when I try to use std::make_shared
with the std::initializer_list
as argument I got errors:
auto example = new Derived({
{ 0, std::make_shared<Derived>({
{ 0, std::make_shared<Derived>() }
}) }
});
您可以在实时预览。
错误:函数参数太多...
error: too many arguments to function...
只有当我这样做(实时预览)时,它才能工作:
It works only when I do this (live preview):
auto example = new Derived({
{ 0, std::make_shared<Derived>(std::initializer_list<std::pair<int, std::shared_ptr<Base>>> {
{ 0, std::make_shared<Derived>() }
}) }
});
我想知道的是:为什么只有当我通过而不是使用
>就像这样: {{}}
作为 std :: make_shared
上的参数的std :: initializer_list
What I want to know is: Why it works only when I pass the std::initializer_list
as argument on std::make_shared
instead of using {{}}
just like this:
auto example = new Derived({ { 0, std::make_shared<Base>() } });
可以让 std :: make_shared
接受它?
提前感谢。
推荐答案
要工作,您需要创建一个自定义 make_shared_from_list
,因为 make_shared
不支持非显式初始化列表。 @brian描述了原因。
For this to work, you need to create a custom make_shared_from_list
, as make_shared
does not support non-explicit initializer lists. The reason is described well by @brian.
我将使用traits类将 T
映射到
I would use a traits class to map a type T
to the type of initializer list.
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) );
}
或类似的东西。
或者,直接将 {...}
转换到 initializer_list< blah>
在理论上,足够的反射元编程支持将允许 shared_ptr
做这个没有traits类,位是相当遥远的管道。
In theory, sufficient reflection metaprogramming support would allow shared_ptr
to do this without the traits class, bit that is pretty far down the pipe.
这篇关于std :: make_shared和std :: initializer_list的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!