c++ - 解压一个类型列表

标签 c++ templates c++14 variadic-templates c++17

假设我有一个只接受类型模板参数的函数,我无法更改它的定义/实现。

template < typename T >
void do_it();

现在我有一个按常规方式定义的类型列表,也不能更改它:

template< typename ...Ts >
struct typelist;

我想实现一个函数,它接受一个类型列表,并在每个类型上运行 do_it():

template< typename List >
void do_them();

到目前为止我找到的唯一解决方案是:

template< typename T >
void do_them_impl()
{
   do_it<T>();
}

template< typename T, typename Ts...>
void do_them_impl()
{
   do_it<T>();
   do_them_impl<Ts...>();
}

template< template < typename...> class List, typename ...Ts >
void do_them_extract( List<Ts...>&& )
{
    do_them_impl< Ts >(); 
}

template< typename List >
void do_them()
{
    do_them_impl( List{} ); 
}

但这需要 4(!)个函数,我想为每个案例创建一个 do_them 函数。我将需要其中的很多,而且我不想为每个函数编写四个函数。我错过了什么吗?

欢迎使用 C++14,也欢迎使用 C++17 解决方案,但要这样标记。

最佳答案

在 C++14 中,您可以使用一些糟糕的技巧来引入有效的包扩展上下文:

template< template < typename...> class List, typename ...Ts >
void do_them_impl( List<Ts...>&& )
{
    (void)std::initializer_list<int> {
        (do_it<Ts>(), 0)...  
    };
}

template< typename List >
void do_them()
{
    do_them_impl( List{} ); 
}

这允许您避免递归模板实例化,这通常更昂贵。

Live Demo


在 C++17 中你可以使用 fold expressions :

template< template < typename...> class List, typename ...Ts >
void do_them_impl( List<Ts...>&& )
{       
    (do_it<Ts>(), ...);
}

template< typename List >
void do_them()
{
    do_them_impl( List{} ); 
}

Live Demo

关于c++ - 解压一个类型列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42002126/

相关文章:

c++ - 如何将模板转换为模板 pre C++11

c++ - 表达式未评估为常量两级 constexpr 函数(编译器错误?)

c++显式调用构造函数和临时对象

c++ - 除以 sizeof(void *) 是什么意思?

c++ - 我可以使用元编程将类型列表转换为对列表中的每种类型具有特定隐式转换行为的新类型吗?

c++ - 调用没有命名空间的方法

c++ - C++ 14和c++ 17中相同代码的不同输出

c++ - 强制线程在销毁前离开对象

c++ - 可变模板参数 : can I pick reference vs value depending on type?

c++ - 从函数返回时的右值引用行为