3
Vote me down if you have too, but here is answer number 3 :) I might remove one of the previous two but having them all 3 + Bens concept & answer, gives nice chronological view.
As in my second answer, I am using std::common_type
. This variant is just more modern and cleaner.
template< class, class = void_t<> >
struct
has_type : false_type { };
template< class T >
struct
has_type<T, void_t<decltype(declval<T::type>())>> : true_type { };
template<typename SIG, typename FP >
constexpr inline bool signature_fp_match(FP)
{
using c_t = common_type< SIG, FP >;
return has_type<c_t>{}();
}
Here is the usage
template<typename T, typename ... A>
using RequiredSignature = bool(T&, A ... a);
bool ok_fun(int& ) { return true; }
static_assert( signature_fp_match< RequiredSignature<int> >(ok_fun) );
Or the less snazzy variation:
static_assert( signature_fp_match< bool(int&) >(ok_fun) );
For a more generic utility rename signature_fp_match
to have_common_type
or whatever you fancy.