user2746401
user2746401

Reputation: 3406

Errors with std::enable_if<>

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

Upvotes: 1

Views: 795

Answers (2)

Andy Brown
Andy Brown

Reputation: 12999

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.

Upvotes: 1

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153820

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

Upvotes: 5

Related Questions