mercredi 28 septembre 2016

SFINAE to determine if a type has a potentially overloaded method

I was looking for an SFINAE solution to check at compile time if a type has a method. My goal is to check if a type is a valid "duck type", but instead of a useless compile error, I want to use static_assert to provide an informative message.

I found [this question], which provides a fairly good answer to my problem, except it fails when the type provides overload to the method:

template<typename...> // parameter pack here
using void_t = void;

template<typename T, typename = void>
struct has_xxx : std::false_type {};

template<typename T>
struct has_xxx<T, void_t<decltype(&T::xxx)>> :
  std::is_member_function_pointer<decltype(&T::xxx)>{};

This works fine with the following example, and differentiate method and member variable:

struct Foo { int xxx() {return 0;}; };
struct Foo2 {};
struct Foo3{ static double xxx;};
double Foo3::xxx = 42;

int main() {
   static_assert(has_xxx<Foo>::value, "");
   static_assert(!has_xxx<Foo2>::value, "");
   static_assert(!has_xxx<Foo3>::value, "");
}

Original live demo

The code fails if there is an overload:

struct Foo { int xxx() {return 0;}  void xxx(int){} };

int main() {
   static_assert(has_xxx<Foo>::value, "");
}

Failing live demo with overloaded method

How can this code be improved to handle overloading?

Aucun commentaire:

Enregistrer un commentaire