Consider the following, I want to check if the types I pass off to some other function sf
has a member function T::mf
that is required by sf
, I know the return type and the name but there can by any number of overloads.
After some tinkering (well it is fun..) and googling , I can get something like the code below to work, the problem is that I don't know how to express that print
can have a variable number of arguments.
#include <type_traits>
#include <utility>
template <typename T,typename = void>
struct has_write : std::false_type {};
template <typename T>
struct has_write<T, decltype(std::declval<T>().write())> : std::true_type {};
template <typename T, typename R = void , typename ...Args>
struct has_print : std::false_type {};
// cant deduce, specialization never used
template <typename T, typename ...Args>
struct has_print<T, decltype(std::declval<T>().print(std::declval<Args>()...))> : std::true_type {};
struct Foo {
void write();
};
struct Bar {
int print(int, float, int);
};
int main(){
static_assert(has_write<Foo>::value, "Does not have write..");
static_assert(has_print<Bar>::value, "Does not have print..");
return 0;
}
The above compiles with g++
but the second assert
fails, clang
is a bit more helpful and tells me that the specializations for has_print
will never be used because it cannot deduce all the types.