Given three different empty structs, A, B and C, I want to have a function foo accept any combination of any number of these three parameters, e.g.:
struct A {};
struct B {};
struct C {};
// Foo has a required parameter that must be the first one given. Anything else is optional.
foo(1);
foo(1, A{});
foo(1, B{});
foo(1, B{}, A{});
foo(1, A{}, C{}, B{});
I thought variadic templates and function overloading would help in this situation, so here's what I've tried:
struct A {};
struct B {};
struct C {};
template <typename... ExtraParams>
void foo(int x, ExtraParams&&...)
{
std::cout << "x = " << x;
}
template <typename... ExtraParams>
void foo(int x, A&&, ExtraParams&&... extra)
{
foo(x, extra...);
std::cout << " with A";
}
template <typename... ExtraParams>
void foo(int x, B&&, ExtraParams&&... extra)
{
foo(x, extra...);
std::cout << " with B";
}
// same for C
However, when calling f(2, A{}, B{}), only x = 2 with A gets printed. I think I undestand why this does not work, but I am not quite sure how I should actually be dealing with this situation.
EDIT The code I was testing against used rvalue reference for the type considered known, e.g.:
template <typename... ExtraParams>
void foo(int x, A&&, ExtraParams&&... extra)
{
foo(x, extra...);
std::cout << " with A";
}
and this will generate the exact behavior I mentioned (I don't know why though).