{} requires you to initialize something of a certain type.
C ++ 11 variable arguments require your types to be subtracted.
These are opposite requirements.
Now I could generate an object with a set of overloads () to some large finite number.
namespace details { template<std::size_t, class T> using ignore_index=T; template<class T, class Count, class Base> struct linear_overload_count; template<class T, std::size_t I0, std::size_t...Is, class Base> struct linear_overload_count<T, std::index_sequence<I0,Is...>, Base>: linear_overload_count<T, std::index_sequence<Is...>, Base> { using linear_overload_count<T, std::index_sequence<Is...>, Base>::operator(); using linear_overload_count<T, std::index_sequence<Is...>, Base>::linear_overload_count; std::result_of_t< Base const&(T const&, ignore_index<Is,T>const&...) > operator()(T const& t0, ignore_index<Is,T>const&...ts) const { return Base::operator()(t0, ts...); } linear_overload_count()=default; linear_overload_count(linear_overload_count const&)=default; linear_overload_count(linear_overload_count &&)=default; linear_overload_count& operator=(linear_overload_count const&)=default; linear_overload_count& operator=(linear_overload_count &&)=default; }; template<class T, class Base> struct linear_overload_count<T, std::index_sequence<>, Base>: Base { using Base::Base; linear_overload_count(Base&& b):Base(std::move(b)) {} linear_overload_count(Base const& b):Base(b) {} std::result_of_t< Base const&() > operator()() const { return Base::operator()(); } linear_overload_count()=default; linear_overload_count(linear_overload_count const&)=default; linear_overload_count(linear_overload_count &&)=default; linear_overload_count& operator=(linear_overload_count const&)=default; linear_overload_count& operator=(linear_overload_count &&)=default; }; } template<class T, std::size_t N, class Base> using linear_overload_Ts = details::linear_overload_count<T, std::make_index_sequence<N>, Base>; auto count_args_impl = [](auto&&...args) { std::cout << sizeof...(args) << "\n"; }; struct bob { int x,y; }; using count_bobs_t = linear_overload_Ts< bob, 3, decltype(count_args_impl) >; count_bobs_t const bobs = count_args_impl; int main() { bobs(); bobs({}, {}, {1,2}); }
living example .
Now we can have up to 100 overloads in bobs , changing the number 3 above to 100 .
Note that if you press more than 100, your compiler will die . This can be fixed with inheritance of the binary tree instead of the linear one, but I cannot worry.
In addition, this method may slow down compilation.
Note that Base must be a type. You can use lambda as described above to go to your template function (give them different names), a manual function object, or something else.
Using this method to create a function instead of a function object is not something that I can solve without using the type named in the call (so use ADL to search for the generated function). Function objects do not participate in overload resolution in the same way as functions do, which can be a problem.
It also seems like a lot of work to do away with adding an extra set of {} .