Search code examples
c++templatesc++11sfinaecompiler-bug

VC++ SFINAE gives error C2070: 'overloaded-function': illegal sizeof operand


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?


Solution

  • 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.