実際には、アンパック操作で 2 つの異なるパラメーターのパックを一度にターゲットにすることができます (それらは同じ長さである必要があると思います)。ここでは、型のパックと数値のパックが必要です。
次のようなもの:
template <typename C, typename... T, size_t... N>
C* init_from_tuple_impl(bp::tuple tpl) {
return new C{ bp::extract<T>(tpl[N])... };
}
インデックスのパックを生成する必要があるのは「ただ」:
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;
};
そしてそれを使用します:
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: 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>
]':
まさに私たちが望んでいたものです:)