如何使用数字序列解压缩可变参数模板参数? [英] How to unpack a variadic template parameter with a numeric sequence?

查看:86
本文介绍了如何使用数字序列解压缩可变参数模板参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何(或有可能)使用数字序列解压缩参数包?例如,

 模板< typename C,typename ... T& 
C * init_from_tuple(bp :: tuple tpl)
{
return new C {bp :: extract< T& // }

- 行应该展开为

  return new C {bp :: extract< T0> [0]),
bp :: extract< T1>(tpl [1]),
.....
bp :: extract ;

其中 n == sizeof ...(T) code>。



目的是为Boost.Python创建一个__init__函数,接受具有预定义类型的元组。


<实际上,解压缩操作可以同时定位两个不同的参数包(我认为它们需要具有相等的长度)。



类似的东西:

  template< typename C,typename ... T,size_t ... N> 
C * init_from_tuple_impl(bp :: tuple tpl){
return new C {bp :: extract T(tpl [N])...}
}



我们只是需要生成一组索引:

 模板< size_t ... N> struct Collection {}; 

template< typename C> struct ExtendCollection;

template< size_t ... N>
struct ExtendCollection<集合< N ...> > {
typedef Collection< N ...,sizeof ...(N)>类型;
};

template< typename ... T>
struct GenerateCollection;

模板<>
struct GenerateCollection<> {typedef Collection<>类型; };

template< typename T0,typename ... T>
struct GenerateCollection< T0,T ...> {
typedef typename ExtendCollection<
typename GenerateCollection< T ...> :: type
> :: type type;
};

然后使用它:

  template< typename C,typename ... T,size_t ... N> 
C * init_from_tuple_impl(bp :: tuple tpl,Collection< N ...>){
return new C {bp :: extract T(tpl [N])...}
}

template< typename C,typename ... T>
C * init_from_tuple(bp :: tuple tpl){
typename GenerateCollection< T ...> :: type collection;
return init_from_tuple_impl< C,T ...>(tpl,collection);
}



我们可以通过在执行时犯错误来看到正确性。 init_from_tuple_impl (例如删除 new ):

  template< typename C,typename ... T,size_t ... N> 
C * init_from_tuple_impl(bp :: tuple tpl,Collection< N ...>){
return C {bp :: extract T(tpl [N])...}
}

Ideone

  prog.cpp:在函数'C * init_from_tuple_impl :: tuple,Collection< N ...>)
[with
C = bp :: Object,
T = {int,float,char},
unsigned int ... N = {0u,1u,2u},
bp :: tuple = std :: basic_string< char>
]':

正是我们想要的:)


How to (or is it possible to) unpack a parameter pack with a numeric sequence? For example,

template <typename C, typename... T>
C* init_from_tuple(bp::tuple tpl)
{
   return new C{bp::extract<T>("magic"(tpl))...}; // <--
}

which the <-- line should expand to

   return new C{bp::extract<T0>(tpl[0]),
                bp::extract<T1>(tpl[1]),
                .....
                bp::extract<Tn>(tpl[n])};

where n == sizeof...(T) - 1.

The purpose is to create a __init__ function for Boost.Python which accepts a tuple with predefined types.

解决方案

Actually, it is possible for the unpack operations to target two different packs of parameters at once (I think they need be of equal length). Here we would like a pack of types, and a pack of numbers.

Something akin to:

template <typename C, typename... T, size_t... N>
C* init_from_tuple_impl(bp::tuple tpl) {
  return new C{ bp::extract<T>(tpl[N])... };
}

We "just" need to generate the pack of indices:

template <size_t... N> struct Collection {};

template <typename C> struct ExtendCollection;

template <size_t... N>
struct ExtendCollection< Collection<N...> > {
  typedef Collection<N..., sizeof...(N)> type;
};

template <typename... T>
struct GenerateCollection;

template <>
struct GenerateCollection<> { typedef Collection<> type; };

template <typename T0, typename... T>
struct GenerateCollection<T0, T...> {
  typedef typename ExtendCollection<
    typename GenerateCollection<T...>::type
  >::type type;
};

And then use it:

template <typename C, typename... T, size_t... N>
C* init_from_tuple_impl(bp::tuple tpl, Collection<N...>) {
  return new C { bp::extract<T>(tpl[N])... };
}

template <typename C, typename... T>
C* init_from_tuple(bp::tuple tpl) {
  typename GenerateCollection<T...>::type collection;
  return init_from_tuple_impl<C, T...>(tpl, collection);
}

In action at Ideone.

We can witness the correctness by making a "mistake" in the implementation of init_from_tuple_impl (remove the new for example):

template <typename C, typename... T, size_t... N>
C* init_from_tuple_impl(bp::tuple tpl, Collection<N...>) {
  return C { bp::extract<T>(tpl[N])... };
}

In action at Ideone:

prog.cpp: In function 'C* init_from_tuple_impl(bp::tuple, Collection<N ...>)
[with
    C = bp::Object,
    T = {int, float, char},
    unsigned int ...N = {0u, 1u, 2u},
    bp::tuple = std::basic_string<char>
]':

Exactly what we wanted :)

这篇关于如何使用数字序列解压缩可变参数模板参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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