jeudi 28 juillet 2016

std::enable_if does not disable a method

I try to use enable_if in order to call a method or another using SFINAE, but my code does not compil since it tries to call a method with an unknown signature (the enable_if for me was here to avoid this...)

here is my code :

#include <iostream>

class A
{
public:
   bool Set1(int)
   {
      std::cout << 1 << std::endl;
      return true;
   }

   template <typename V>
   bool Set2(int, V&)
   {
      std::cout << 2 << std::endl;
      return true;
   }
};


#define DEFINE(name)\
\
template<typename T, typename V>\
struct HasTemplateMethod##name\
{\
    template<typename U, bool (U::*)(int, V&)> struct SFINAE {};\
    template<typename U> static char Test(SFINAE<U, &U::/**/name>*);\
    template<typename U> static int Test(...);\
    static const bool Has = sizeof(Test<T>(0)) == sizeof(char);\
};\
\
\
template<typename T, typename V>\
struct HasMethod##name\
{\
    template<typename U, bool (U::*)(int)> struct SFINAE {};\
    template<typename U> static char Test(SFINAE<U, &U::/**/name>*);\
    template<typename U> static int Test(...);\
    static const bool Has = sizeof(Test<T>(0)) == sizeof(char);\
    static const bool Crap = sizeof(V) == sizeof(V);\
};\
\
template<typename V>\
typename std::enable_if<HasMethod##name<A, V>::Has, bool>::type \
name(int i, V& v) \
{ \
   return this->a./**/name(i); \
}; \
 \
template<typename V>\
typename std::enable_if<HasTemplateMethod##name<A, V>::Has, bool>::type \
name(int i, V& v) \
{ \
   return this->a./**/name(i, v); \
}; \

class Call
{
   public:
   DEFINE(Set1)
   DEFINE(Set2)

   Call()
   {
      int o;
      std::cout << HasMethodSet1<A, int>::Has << std::endl;
      std::cout << HasTemplateMethodSet1<A, int>::Has << std::endl;
      std::cout << HasMethodSet2<A, int>::Has << std::endl;
      std::cout << HasTemplateMethodSet2<A, int>::Has << std::endl;
   }

   A a;
};


int main()
{
   Call c;
   int o;

// c.Set1(1, o);
// c.Set2(1, o);

}

if you comment this call :

return this->a./**/name(i); \ 

it will build and you can see the output will be 1 0 0 1 which make sense. so I don't get why the enable_if does not make his job (surely because of the template but I am stuck here).

If you wonder why I have this crap variable it was just a test to use V in the HasMethodSet2 struct.

Thanks for your help.

Aucun commentaire:

Enregistrer un commentaire