Nanashi No Gombe
Nanashi No Gombe

Reputation: 630

Single template parameter pack for multiple variadic functions?

Usually we would do something like this to define multiple variadic functions taking the same parameter pack:

template<typename ...Pack>
void func1(Pack... params);

template<typename ...Pack>
void func2(Pack... params);

template<typename ...Pack>
void func3(Pack... params);

template<typename ...Pack>
void func4(Pack... params);

Is there some way to avoid this redundant repetition? For example, something like:

template<typename ...Pack>
{
    void func1(Pack... params);
    void func2(Pack... params);
    void func3(Pack... params);
    void func4(Pack... params);
}

Upvotes: 2

Views: 77

Answers (3)

max66
max66

Reputation: 66230

If you can use C++17... maybe you can define a single function, with an additional template parameter that is the number of the function, and use if constexpr to separate the bodies of the single functions.

I mean something as follows

template <int Id, typename ... Pack>
void func (Pack ... params)
 {
   if constexpr ( 1 == id )
    { /* body of func1() */ }
   else if constexpr ( 2 == id )
    { /* body of func2() */ }
   else if constexpr ( 3 == id )
    { /* body of func3() */ }
   // else // etc...
 }

Calling func() you have to explicit the integer template parameter

func<1>("abc"); // equivalent to func1("abc");

As observed by Nathan Oliver, when names of functions are important and descriptive (and not a simple enumeration), the use of a integer template parameter gives you a loose of description.

In this case, instead of an int, you can add an enum value additional template parameter. With descriptive names for enum values.

Something as

enum funcId
 {
   a_complex_and_descriptive_func_id,
   another_complex_func_id,
   a_third_complex_func_id // , etc...
 }     

template <funcId Id, typename ... Pack>
void func (Pack ... params)
 {
   if constexpr ( a_complex_and_descriptive_func_id == id )
    { /* body of first function */ }
   else if constexpr ( another_complex_func_id == id )
    { /* body of second function */ }
   else if constexpr ( a_third_complex_func_id == id )
    { /* body of third function */ }
   // else // etc...
 }

and the call become

func<a_complex_and_descriptive_func_id>("abc");

Upvotes: 2

rezaebrh
rezaebrh

Reputation: 431

Try wrap them inside a struct. If you want them independent from any object state you should declare them static.

template <typename ...Pack>
struct FunctionHolder
{
    static void func1(Pack... params);

    static void func2(Pack... params);
};

LIVE SAMPLE

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 181067

Pre C++20 answer: No, there isn't anything you can do to get a syntax like that. Best you could do is create a macro that does a lot of the work for you.

C++20: You can use auto for the function parameter type which is syntactic sugar for writing out a template like it is for a lambda currently. That would give you

void func1(auto... params);
void func2(auto... params);
void func3(auto... params);
void func4(auto... params);

Upvotes: 3

Related Questions