Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select every even (or odd) argument in template parameter pack

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?

like image 911
Bartłomiej Siwek Avatar asked Jun 25 '11 03:06

Bartłomiej Siwek


People also ask

Can we pass Nontype parameters to templates?

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.

What is Variadic template in C++?

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.

Can a template be a template parameter?

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.)

What is a parameter pack in C++?

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.


1 Answers

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.

like image 197
Ise Wisteria Avatar answered Oct 24 '22 14:10

Ise Wisteria