将参数包解压缩到std :: initializer_list中?

时间:2018-08-12 17:29:38

标签: c++ c++11 templates variadic-templates

是否可以使用参数包创建对象的初始化列表或将对象插入std::vector中?我遇到的问题是我看到的所有参数包示例,都使用了传递给编译器的参数来区分编译器需要调用哪个函数。问题是我没有参数可以传递给函数,而只是类型。

示例:

// compiler cannot determine which function is correct
namespace impl
{
    template<class T, class... U>
    void get_type_impl(std::vector<MetaClass*>& types)
    {
        // rusty::get<T>(); just retrieves a MetaClass object for the specified type
        types.emplace_back(rusty::get_type<T>());
        impl::get_type_impl<U...>(types);
    }

    template <class T>
    void get_type_impl(std::vector<MetaClass*>& types)
    {
        types.emplace_back(rusty::get_type<T>());
    }
}

template <class... T>
std::vector<MetaClass*> get_types()
{
    std::vector<MetaClass*> types;
    types.reserve(sizeof...(T));
    impl::get_type_impl<T...>(types);
    return types;
}

示例用法:

auto types = get_types<MovementComponent, GraphicsComponent>();

编辑:

目标是创建由提供的模板类型创建的对象向量。我当前遇到的问题是编译器无法推断要使用哪个函数。由于两个get_type_impl可以具有相同的功能签名。

解决方案:

namespace impl
{
    template <class T>
    void get_type_impl(std::vector<MetaClass*>& types)
    {
        types.emplace_back(rusty::get_type<T>());
    }
    template<class T0, class T1, class... Tn>
    void get_type_impl(std::vector<MetaClass*>& types)
    {
        types.emplace_back(rusty::get_type<T0>());
        impl::get_type_impl<T1, Tn...>(types);
    }
}

template <class... T>
std::vector<MetaClass*> get_types()
{
    std::vector<MetaClass*> types;
    types.reserve(sizeof...(T));
    impl::get_type_impl<T...>(types);
    return types;
}

解决方案是强制get_type_impl中的一种至少采用2种模板类型,而另一种则简单地采用1。这在签名中产生了足够的差异,以便编译器确定哪个是正确的函数。

1 个答案:

答案 0 :(得分:3)

不确定理解,但是...在我看来,您正在寻找以下内容(警告:未经测试的代码):

template <typename ... Ts>
std::vector<MetaClass*> get_types()
 { return { rusty::get_type<Ts>()... }; }

否则,要解决get_types_impl()的问题,建议删除第二个功能

template <class T>
void get_type_impl(std::vector<MetaClass*>& types)
{
    types.emplace_back(rusty::get_type<T>());
}

并用以下基本情况代替

template <int = 0>
void get_type_impl (std::vector<MetaClass*> const &)
 { }

其背后的思想是通过emplace_back()的第一个版本在types中添加(get_types_impl())个元素,并在可变参数类型列表U...时进行最后一次调用是空的,叫做

impl::get_type_impl<>(types);

被劫持(由于使用默认的非类型模板参数int=0)到实际情况。