std :: make_shared和std :: initializer_list [英] std::make_shared with std::initializer_list

查看:176
本文介绍了std :: make_shared和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆