Вопрос

I am wondering if it's possible to combine policy classes using variadic template-template parameters such that each policy may have it's own template pack. It seems like you can only share a single template pack amongst all policies but I hope that's not the case.

The following seems to be what's possible:

template <
    class T,
    template <class, typename...>   class Policy1,
    template <class, typename...>   class Policy2,
    template <class, typename...>   class Policy3,
    typename... Args    
>
struct PolicyClass 
    : public Policy1     <ObjT, Args...>
    , public Policy2     <ObjT, Args...>
    , public Policy3     <ObjT, Args...>    {}

I'm hoping each policy can have it's own pack so I could make something like this (?):

template <class T>
struct implementedPolicy1 {};
template <class T>
struct implementedPolicy2 {};
template <class T, class A>
struct implementedPolicy3 {};

PolicyClass <ObjT, 
             implementedPolicy1,
             implementedPolicy2,
             implementedPolicy3<AType>
            >

The idea being each of the policies are all using the same object type but the third has some further templating. I know that's incorrect code above - just trying to illustrate what I'd like to be able to do.

Thanks

Это было полезно?

Решение 2

You need to be able to delimit between the packs.

// helper template.  Using `std::tuple<>` instead is another option.
template<class...>struct type_list {};

// base, note no body:
template <
    class T,
    template <class, typename...>   class Policy0,
    template <class, typename...>   class Policy1,
    template <class, typename...>   class Policy2,
    typename... Packs
>
struct PolicyClass;

// specialization:
template <
    class T,
    template <class, typename...>   class Policy0,
    template <class, typename...>   class Policy1,
    template <class, typename...>   class Policy2,
    typename... A0s,
    typename... A1s,
    typename... A2s
>
struct PolicyClass<
  T, Policy1, Policy2, Policy3,
  type_list<A0s...>, type_list<A1s...>, type_list<A2s...>
>
: Policy0<T, A0s...>, Policy1<T, A1s...>, Policy2<T, A2s...> {}

where I pack each policies extra arguments into a type_list.

In theory you could do fancier things, like have particular "tag" types being the delimiters, but it ends up being a lot of gymnastics.

PolicyClass< int, bob, eve, alice, type_list<>, type_list<double>, type_list<char, char, char> > foo;

will create

PolicyClass: bob<int>, alice<int, double>, eve<int, char, char, char>

roughly.

Другие советы

I have never been fan of template template parameters, and this is one other instance I would avoid them:

template <typename T, typename... Policies>
struct PolicyClass: Policies... {};

will just work with arbitrary policies:

using PC = PolicyClass<int,
                       LifetimePolicy<LP::Extended>,
                       DurabilityPolicy<3600, DP::Seconds>
                       StoragePolicy<int, SP::InMemory>>;

Note that you may have something like:

template <class T,
          template <class> class Policy1,
          template <class> class Policy2,
          template <class> class Policy3>
struct PolicyClass : public Policy1<ObjT>,
                     public Policy2<ObjT>,
                     public Policy3<ObjT>
{};

template <class T> struct implementedPolicy1 {};
template <class T> struct implementedPolicy2 {};
template <class T, class A> struct implementedPolicy3 {};

// Adapt the policy interface
template <class T>
using myImplementedPolicy3 = implementedPolicy3<T, AType>; // Assuming AType exist

PolicyClass <ObjT, implementedPolicy1, implementedPolicy2, myImplementedPolicy3> policies;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top