I'm trying to do something similar to C++11 variable number of arguments, same specific type, but I have my own type:
struct Foo
{
Foo(int) {}
Foo(int, int) {}
};
with a bunch of overloads
void f() {}
void f(const Foo&) {}
void f(const Foo&, const Foo&) {}
// etc. ... as many f() overloads as needed ...
works as desired: f(); f(1); f(1, 2); f(1, { 2, 3 });
.
Instead of overloads, I can also use std::initializer_list<>
with the {}
syntax (as suggested here):
void g_(std::initializer_list<Foo>) {}
g_({}); g_({ 1 }); g_({ 1, 2 }); g_({ 1, { 2, 3 } });
but that has an extra set of {}
(yeah, it's just two characters). To match the syntax of f()
exactly, use a macro:
#define g(...) g_({__VA_ARGS__})
g(); g(1); g(1, 2); g(1,{ 2, 3 });
(Matching the syntax of f()
exactly might be needed because of legacy or generated code. ... and it—arguably—just "looks better".)
But I can't find a way to make a variadic template work
void h() { }
template<typename... T>
void h(const Foo&, T...) { }
h()
, h(1)
and h(1, 2)
work, but h(1, {2, 3})
fails to compile because the compiler can't figure out the type of {2, 3}
as it can with f()
and g_()
.
Is there a way to make f()
work without multiple overloads? Or for g()
to work without a macro? g()
is very close (only one function and no template magic), but there's that macro ...