To choose one of the overloaded functions, at least you have to tell compiler the argument types of the target function. So we can add them as type arguments of the template class mixed_dispatch
template < typename Tag, typename... Args >
class mixed_dispatch {
std::function<void(Tag,Args...)> invoke;
public:
// for overloaded functions
mixed_dispatch( void(&f)(Tag,Args...) ) : invoke( f ) { }
// for function objects
template < typename F >
mixed_dispatch( F&& f ) : invoke( std::forward<F>(f) ) { }
void operator()( Args... args ) const {
invoke( Tag(), args... );
}
};
Now mixed_dispatch
becomes a wrapper which helps you passing Tag
objects to the target function. As you see, we need to change signature of target function(a bit works).
void fun_impl(A1, bool) { std::cout << "A1\n"; }
In client code, like fun
:
template< typename T >
void fun( bool b, T )
{
using dispatcher = mixed_dispatch<T,bool>;
dispatcher d = fun_impl;
d( b );
}