Is it possible to typedef a parameter pack? For example
template<class T, class... Args>
struct A
{
typedef T Type; // We typedef it, then its derived class can use it.
// How about for parameter packs?
// Option 1:
typedef Args Arguments;
// Option 2:
using Arguments = Args;
// Option 3: I can put in a tuple, but how can I untuple it to a pack
typedef tuple<Args...> Tuple;
};
I want to using the above technique to implement the following
template<int... VALUES>
struct IntegralSequence
{
enum { SIZE = sizeof...(VALUES) };
template <unsigned I>
struct At
{
enum { VALUE = typename tuple_element<I,
tuple<integral_constant<int, VALUES>...>>::type::value
};
};
};
template<unsigned N>
struct AscendingSequence
{
typedef IntegralSequence<AscendingSequence<N-1>::VALUES..., N> Type;
using VALUES = Type::VALUES; // if it works
};
template<>
struct AscendingSequence<1>
{
typedef IntegralSequence<0> Type;
using VALUES = Type::VALUES; // if it works
};
Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.
Pack expansion A pattern followed by an ellipsis, in which the name of at least one parameter pack appears at least once, is expanded into zero or more comma-separated instantiations of the pattern, where the name of the parameter pack is replaced by each of the elements from the pack, in order. template<class...
You can pack them in a tuple
, or in a arbitrary empty class template (I prefer to call it pack
):
template<typename... Args>
struct pack { };
template<class T, class... Args>
struct A
{
using args = pack<Args...>;
};
If you are then given A
e.g. in function template and you want to deduce Args...
, you can do it like this:
template<typename... Args, typename A>
void f(pack<Args...>, A a) { /* use Args... here */ }
template<typename A>
void f(A a) { f(typename A::args(), a); }
pack
being empty is convenient in situations like that. Otherwise you'd need some other means to pass args
without actually passing a tuple
that contains data (e.g. wrapping it into yet another empty struct).
Or, in a class template specialization:
template<typename T, typename = typename T::args>
struct B_impl;
template<typename T, typename... Args>
struct B_impl <T, pack<Args...> >
{
// use Args... here
};
template<typename T>
using B = B_impl<T>;
I guess these are the options of deduction and partial specialization that @dyp mentioned.
EDIT This is in response to the edited question. Ok, this is clearly an XY problem. If IntegralSequence
is all you need, you can use std::make_integer_sequence
in C++14 or check my answer to another question just a few minutes ago for an efficient implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With