Question

I would like to define a class which takes a list of non-type parameters, potentially of different types. For example, the following should be valid:

Test<3, 4.5, 6> t;

If all parameters had the same type, say int, I could use the following definition:

template<int... args>
class Test {
  // ...
};

To be more specific, in my specific use case there is a second class Base with a number of members, and I would like to pass Base member pointers.

Test<&Base::a, &Base::b>

If Base::a and Base::b have a common type T, then I could define Test as follows.

template<int Base::* ...args>
class Test {
  //
};

How can I go about defining such a class Test?

Was it helpful?

Solution

You can do it in the following way:

template <class... Types>
struct Wrapper
{
    template <Types... args>
    class Test {
        // ...
    };
};

Note that simple notation template <class... Types, Types... args> class Test; is not permitted by standard (see paragraph [temp.param] 14.1/15).

Example of using (note that float, double and long double constants can not be non-type template parameters):

Wrapper<int, char, unsigned>::Test<1, '2', 3U> t;

More specific case with pointers to members can be implemented similarly:

struct Base
{
    int a;
    float b;
    void c() {}
};

template <class... Types>
struct Wrapper
{
    template <Types Base::*... args>
    class Test {
        //
    };
};

Example of using:

Wrapper<int, float, void ()>::Test<&Base::a, &Base::b, &Base::c> t2;

This notation can be shortened using variadic macro and decltype keyword.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top