Similarily to this question is it possible to use SFINAE to determine if a type has a member function with a certain argument(s)? Without the argument list as answered in the other question and the std::void_t
example says it works fine. (I stood with the latter.) However, If I try to add a check for argument lust with extra std::decltype<>()
it fails with template parameters not deducible in partial specialization
. Is there any way to extend this method to check for certain argument types?
Example code:
#include <type_traits>
class A {
public :
void a(){}
void b(int val){}
};
class B {
public :
void b(float val){}
};
// --- Has function a() without arguments
template <typename T, typename = void> struct has_a : std::false_type
{
};
template <typename T> struct has_a<T, std::void_t<decltype(std::declval<T>().a())>> : std::true_type
{
};
template <typename T> constexpr bool has_a_v = has_a<T>::value;
// This is OK:
static_assert(true == has_a_v<A>);
static_assert(false == has_a_v<B>);
// --- Has function b() with one argument of one given type
template <typename T, typename U, typename = void> struct has_b : std::false_type
{
};
template <typename T ,typename U> struct has_b<T, std::void_t<decltype(std::declval<T>().b(std::declval<U>()))>> : std::true_type
{
};
template <typename T, typename U> constexpr bool has_b_v = has_b<T, U>::value;
// This fails with `template parameters not deducible in partial specialization`:
static_assert(true == has_b_v<A, int>);
static_assert(false == has_b_v<B, int>);
static_assert(false == has_b_v<A, float>);
static_assert(true == has_b_v<B, float>);
int main () { return 0;}