Reputation: 3406
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
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
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