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.

1
  • 1
    You'll have to use specialisation/SFINAE. Commented Jan 14, 2013 at 23:03

2 Answers 2

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.)

Sign up to request clarification or add additional context in comments.

3 Comments

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.
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: That sounds much more like a dynamic problem, not a static one.
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.

6 Comments

Argh. Please, don't post va_list on C++ questions ever.
@BartekBanachewicz Could you please explain what are your concerns ?
@user1715664 What do you think about the solution I posted above ?
There are numerous resources on the web that will explain it better to you. Something that should immediately caught your attention is that it's also in C.
@BartekBanachewicz in all examples I saw in the web, it shows that it works in c/c++ it is a probably a bad way to do things but that is a part of the language and people still use it, if you have cons you can mention them your comments could be more beneficial for the audience.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.