I would like to allow use of the class I'm writing to specify as a template parameters a list of types along with a list of allocators of those types in a manner that types are at odd positions and allocators are at even ones:
template<typename... T>
class MyClass {
// Stuff inside
}
int main() {
MyClass<SomeType1, AllocatorOfSomeType1> c1;
MyClass<SomeType1, AllocatorOfSomeType1,
SomeType2, AllocatorOfSomeType2> c2;
MyClass<SomeType1, AllocatorOfSomeType1,
SomeType2, AllocatorOfSomeType2,
SomeType3, AllocatorOfSomeType3> c3;
// And so on....
}
Internally it would make sense to have a tuple of vectors of types for storage:
std::tuple<std::vector<EveryOddTypeInParameterPack>...> m_storage_;
and a tuple of allocators for usage:
std::tuple<std::vector<EveryEvenTypeInParameterPack>...> m_storage_;
How can I actually declare those tuples in code? In theory I need to somehow select every odd/even type in parameter pack - is that possible?
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
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.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
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.
Though the code got a little lengthy, I suppose the mechanism doesn't have
unnecessary peculiarities.
If I understand the question correctly,
probably the following code will meet the purpose:
// push front for tuple
template< class, class > struct PFT;
template< class A, class... T > struct PFT< A, tuple< T... > > {
typedef tuple< A, T... > type;
};
// for even
template< class... > struct even_tuple;
template< class A, class B > struct even_tuple< A, B > {
typedef tuple< A > type;
};
template< class A, class B, class... T > struct even_tuple< A, B, T... > {
typedef typename PFT< A, typename even_tuple< T... >::type >::type type;
};
// As for odd elements, in the same way as even(please see the test on ideone)
// objective type
template< class > struct storage_type;
template< class... T > struct storage_type< tuple< T... > > {
typedef tuple< vector< T >... > type;
};
template< class... T >
struct MyClass {
typename storage_type< typename even_tuple< T... >::type >::type
m_storage_even_;
typename storage_type< typename odd_tuple< T... >::type >::type
m_storage_odd_;
};
Here is a test on ideone.
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