1

I'm trying to use a basic SFINAE pattern in C++ with STL std::enable_if<> and failing at the first hurdle:

#include <type_traits>

template< typename T >
typename std::enable_if< true, bool >::type    // compiles fine
//std::enable_if< false, bool >::type // lots of errors
myFunction( T val )
{
    // do stuff
    return true;
}

void main()
{
    int i = 0;
    myFunction( i );
}

In the first case, enable_if<true,bool> simply works as expected. In the second case, enable_if<false,bool> I'd expect the compilation to fail with just a single error along the lines of 'myFunction': identifier not found but instead I get multiple errors starting with 'type' : is not a member of 'std::enable_if<false,bool>' and then some more error propagating from there.

On the one hand, the compiler does give an error but, on the other hand, I thought the whole point was that Substitution Failure Is Not An Error? Am I missing a very obvious point? Or is VC 2013 having SFINAE issues?

Thanks

user2746401
  • 3,157
  • 2
  • 21
  • 46
  • `enable_if` forces an undefined return type when the first template-argument is `false`. For more info I'd suggest reading: http://stackoverflow.com/q/25284499/2642059 – Jonathan Mee Nov 23 '15 at 12:09

2 Answers2

5

When you use std::enable_if<false, bool>::type literally there is nothing to be substituted. Thus, the code is always wrong and the compilers reports the error as such. SFINAE only applies if there is "S" (substitution) which ended up to "F" (failure).

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
1

The reason is that Visual C++ (and gcc) both implement std::enable_if using a partial specialization for the true case and just an empty struct for the generic case, which is of course what you get for false:

template<bool _Test,class _Ty = void>
struct enable_if
{   // type is undefined for assumed !_Test
};

template<class _Ty>
struct enable_if<true, _Ty>
{   // type is _Ty for _Test
  typedef _Ty type;
};

They've even commented the fact that type is undefined for the false case.

Andy Brown
  • 11,766
  • 2
  • 42
  • 61