0

Say I have a template function that accepts variable arguments and calls other functions with those arguments...

template<typename... A> func(int i, A... args)
{
  // do something common

  switch (i)
  {
    case 0: x(args...); break;
    case 1: y(args...); break;
    case 2: z(args...); break;

    default: break; 
  }

  // do something common
}

...and the other functions are defined as...

void x(int a, int b);
void y(int a, int b);  // note: takes same args as x()
void z(std::string a);

This doesn't compile because calling func() with a std::string argument will not find a match for x() and y() that takes a std::string argument.

Note that func() uses some external criteria (the value of parameter i in this example) to decide which other function to pass parameter args to.

Is there a way to pull this off without resorting to something like stuffing parameter args into a std:tuple and passing that?

[EDIT]

Ok, I figured out an approach that works well enough for my purposes. Here's an example class to illustrate...

class X
{
  private:

    bool a(int) { return true; }
    bool b(int) { return true; }

    template<typename... A> bool a(const A&...) { return false; }
    template<typename... A> bool b(const A&...) { return false; }

  public:

    template<typename... A> void x(int i, const A&... args)
    {
        if (i == 0)
        {
            a(args...);
        }
        else
        {
            b(args...);
        }
    }
};

The variadic template methods for a() and b() will catch any calls made to X.x() where the arguments are not a single int. This resolves the compiler error I was receiving and enables the simpler class API that I was looking for.

user1715664
  • 153
  • 2
  • 10

2 Answers2

2

Yes, make separate overloads:

template <typename A1>
func(A1 arg1)
{
    x(arg1);
}

template <typename A1, typename A2>
func(A1 arg1, A2 arg2)
{
    y(arg1, arg2);
}

template <typename A1, typename A2, typename A3>
func(A1 arg1, A2 arg2, A3 arg3)
{
    z(arg1, arg2, arg3);
}

(Any additional, common code can of course be factored into a separate, common function, possibly a variadic function template.)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Not quite what I was looking for, but it is my fault for not providing enough information. func() may call other methods that take the same argument types (e.g., a(int) and b(int)), but decides which to call based on other criteria (e.g., the value of i). I will edit the question to clear that up. – user1715664 Jan 14 '13 at 23:19
  • The use case I have is a state machine where an event type and its data are passed in. Based on the current state and the event type, the appropriate event handler is called to process the data and potentially advance the state machine. – user1715664 Jan 14 '13 at 23:27
  • @user1715664: That sounds much more like a *dynamic* problem, not a static one. – Kerrek SB Jan 14 '13 at 23:28
0

Take a look at this post I know that you can use ... as a parameter to tell that you are using a variable number of parameters.

... syntax in C++

This is another example with well commented code : Functions with Variable Argument Lists in C and C++ using va_list

I hope this helps.

Mehdi Karamosly
  • 5,388
  • 2
  • 32
  • 50