2

The nature of error is different than the one mentioned in this thread.
I am trying to implement an SFINAE way in VC++ environment which finds if a class contains a member (method) or not.

Below is a simplified code for that:

template<typename Class>
class HasMember_Method
{
  typedef char (&yes)[2];

  template<unsigned int> struct Exists;

  template<typename V>
  static yes CheckMember (Exists<sizeof(&V::Method)>*);  // <--- VC++ problem
  template<typename>
  static char CheckMember (...);

public: 
  static const bool value = (sizeof(CheckMember<Class>(0)) == sizeof(yes));
};

Here Method is the member method we are looking for. This code works perfectly fine in g++ environment even without C++11.
However the same results in a compiler error for buggy VC++:

error C2070: 'overloaded-function': illegal sizeof operand

I tried other workaround for SFINAE using decltype, but no luck. Is there any fix or better work around exist for this problem?

Community
  • 1
  • 1
iammilind
  • 62,239
  • 27
  • 150
  • 297
  • [MSDN says](http://msdn.microsoft.com/en-us/library/hh567368.aspx) they don't support "Expression SFINAE" even in VS2013. – dyp Jan 07 '14 at 12:40
  • Which version of VC do you use ? – Jarod42 Jan 07 '14 at 12:41
  • @Jarod42, it doesn't work in VS2010/12. Both give same errors. Dyp, any alternative using c++11? – iammilind Jan 07 '14 at 12:52
  • 1
    Have you look at solutions in http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence ? – Jarod42 Jan 07 '14 at 12:55
  • In VS2012 or better the solution I gave here: http://stackoverflow.com/a/10707822/1362568 will work, if you know the signature of the method you are probing for. – Mike Kinghan Jan 07 '14 at 15:54
  • @MikeKinghan, I believe with knowing the signature of the method there is more possibility of it working. However that takes away the flexibility. VC++ is supposed to work and unfortunately this bug is up for so long and no progress has been done from their side. Which is sad. The bug I mentioned in my answer is even more dangerous, because it doesn't even result in compilation error. It gives wrong result!!! – iammilind Jan 08 '14 at 04:12

1 Answers1

2

Though below is the not right answer, it at least fixes the issue. In the code snippet, I changed 2 lines:

template<typename Class>
class HasMember_Method
{
  typedef char (&yes)[2];

  template<typename> struct Exists; // <--- changed

  template<typename V>
  static yes CheckMember (Exists<decltype(&V::Method)>*); // <--- changed (c++11)
  template<typename>
  static char CheckMember (...);

public: 
  static const bool value = (sizeof(CheckMember<Class>(0)) == sizeof(yes));
};

And this fixes the compilation issues in VS2010/12!

WAIT! That uncovers another flaw in the buggy VC++ compiler.
It always results in true. :(
The good old g++ works fine here as well.

So the correct answer is to wait for the Microsoft VC++ compiler team to fix these issues.

iammilind
  • 62,239
  • 27
  • 150
  • 297