Home > OS >  Wrapper over a templated class with more than one template parameter pack
Wrapper over a templated class with more than one template parameter pack

Time:02-23

I'm writting a thin wrapper over a class from a third-party library.

My code looks like this:

template<typename TArg1, typename... TPack1, typename... TPack2>
class MyWrapper<TArg1, TPack1..., TPack2...> : protected ThirdParty<TArg1, TPack1..., TPack2...>
{
    // class is empty
};

Where the template parameters of my wrapper mimic the ones in the third party class.

However, my code doesn't compile. The first compiler error I get is:
error C3856: 'MyWrapper': symbol is not a class template

I think it's a problem of my code not giving enough context to the compiler for deducting the template parameter packs. Therefore, they're ambiguous at the MyWrapper level even if they aren't at the ThirdParty level. I've been trying to understand how ThirdParty guarantees it but I haven't so far (and I don't even know if that's the issue).

For full context, the specific case of this problem is me trying to wrap a struct from an ECS library called entt: entt::basic_view.

CodePudding user response:

You don't declare a class template, but something like partial specilization. The correct way should be

template <typename T>
class MyWrapper : protected ThirdParty<T>;

I don't use your template parameters since it contains 2 template parameter pack. The compiler can't know how to split the template arguments.

So I go to see the source code.

template<typename, typename, typename, typename = void>
class basic_view;

template<typename Entity, typename... Component, typename... Exclude>
class basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>> {
}; // get_t / exclude_t is a struct template type.

You can use multiple template parameter packs in the partial specialization.

template <typename T, typename T, typename T, typename T = void>
class MyWrapper;  // without definition neither

template<typename Entity, typename... Component, typename... Exclude>
class MyWrapper<Entity, get_t<Component...>, exclude_t<Exclude...>>: protected basic_view<Entity, get_t<Component...>, exclude_t<Exclude...>> {
};

It works fine, see demo.

  • Related