Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unpacking parameter pack of args into the constructor of each class defined in a variadic template

I'm trying to create a class that inherits from multiple classes (as defined by a variadic template) and, for each class, passes the same parameter pack of args to the constructor of each class. However, it seems as though I'm not able to unpack both the variadic template of classes and the parameter pack of args.

I have a class:

template<class... __Policies>
class GenericPolicyAdapter : public __Policies...{

With constructor:

template<class... __Args>
GenericPolicyAdapter( __Args... args ) : __Policies( args... ){

and test:

GenericPolicyAdapter<T1,T2> generic_policy_adapter( arg1, arg2, arg3 );

gcc fails with:

error: type ‘__Policies’ is not a direct base of ‘GenericPolicyAdapter<T1,T2>’

where __Policies = T1, T2

To clarify, I'm essentially trying to do:

GenericPolicyAdapter : public T1, public T2
{
  public:
    template<class... __Args>
    GenericPolicyAdapter( __Args... args ) : T1( args... ), T2( args... ){}
};

but with T1 and T2 deduced from __Policies

Any ideas? It seems like gcc is treating __Policies as a single type rather than a list of types. Thanks in advance!


Edit:

I should clarify that I'm using gcc/g++ 4.4.5.

The suggestion by Howard Hinnant was to do:

template<class... __Args>
    GenericPolicyAdapter( __Args... args )
        : __Policies( args...)...
    {}

However, with gcc/g++ 4.4.5, this gives invalid use of pack expansion expression. It's great that this works in OSX/clang but is there a way to do this in gcc/g++?

like image 680
ekaszubski Avatar asked Nov 29 '22 03:11

ekaszubski


1 Answers

"..." is a lot like "typename". You just have to keep aggressively sprinkling it around until things compile. :-)

template<class... __Policies>
class GenericPolicyAdapter
    : public __Policies...
{
public:
    template<class... __Args>
        GenericPolicyAdapter( __Args... args )
            : __Policies( args...)...
        {}
};

struct T1
{
    T1(int, int, int) {}
};

struct T2
{
    T2(int, int, int) {}
};

int main()
{
    GenericPolicyAdapter<T1,T2> generic_policy_adapter( 1, 2, 3 );
}
like image 114
Howard Hinnant Avatar answered Dec 05 '22 12:12

Howard Hinnant