Search code examples
c++templatestypesvariadic-templates

Somehow 'using' a list of types (in C++17 and up)


How is is possible to make the following simple idea work?

template <typename ...Types>
void Function()
{ /* do something that depends on the Types */ }

void Test()
{

    using my_types = { int, float };    // not possible
    using my_types = int, float;        // alternative disallowed syntax
    Function<my_types>();
    
    Function<int,float>();              // OK, but I can't specify manually

}

Why is there no direct support for this kind type lists? What's a simple workaround?

Notes

  • this is in a generic context, where I can't manually specify the types I want.
  • I don't want to pass objects of these types to the function. They might be expensive or just not copyable.

To clarify the use case: The user defines a Trait-like class wherein he somehow specifies a list of types. Later, I need to process that list. How he specifies it is still open. So looking for a simple way to do that. No need for the overly complicated 'concat a type-list at compile-time' pattern that can be found here somewhere.


Solution

  • A possible alternative is define a sort of type wrapper (as std::tuple but that do absolutely nothing with template arguments)

    template <typename...>
    struct type_wrapper
     { };
    

    and declare Function() receiving an object of that type

    template <typename ...Types>
    void Function (type_wrapper<Types...> const &)
    { /* do something that depends on the Types */ }
    

    so you can pass an object of the desired wrapper to Function() and let template deduction works

    using my_wrapped_types = type_wrapper<int, float>;
    
    Function(my_wrapped_types{}); 
    

    Why is there no direct support for this kind type lists? What's a simple workaround?

    Because there is std::tuple that cover most use cases and, as you can see, is trivial to write a wrapper when you want something lighter.

    I don't want to pass objects of these types to the function.

    This way, you pass an object of type type_wrapper but no referenced type is instantiated.