Reputation: 967
In the below code example, the second line
std::cout << "is_even (4.4) = " << std::boolalpha << is_even(4.4);
causes compiler failures because no proper substitution is found. If there is an error, then how is this SFINAE? I thought std::enable_if is kind of SFINAE and the acronym means no failure if substitution can't be done. Where I am misinterpreting?
#include <iostream>
#include <type_traits>
template<class T, class = std::enable_if_t<std::is_integral_v<T>>>
bool is_even(T value)
{
return ((value % 2) == 0);
}
int main()
{
std::cout << "is_even (4) = " << std::boolalpha << is_even(4);
std::cout << "is_even (4.4) = " << std::boolalpha << is_even(4.4);
}
Please don't say what i expect in this situation to happen. I am just trying to see how should i see SFINAE here?
Upvotes: 0
Views: 487
Reputation: 1
The error is caused by the call expression is_even(4.4)
. Since you have called a function is_even
by passing a double
, the definition of such a function must exist.
If we call any function, then its definition must exist somewhere. In your case, there is no function named is_even
that takes a double
parameter and hence the error.
SFINAE still works here. For example, when the template argument is deduced to be a double
and then T
is substituted with double
the condition inside std::enable_if_t<std::is_integral_v<T>>
evaluates to false
. Thus this function template is ignored and no error is produced at this point. That is, the error that you're getting is not due to SFINAE. SFINAE doesn't mean that your program won't produce any error.
Now, for the call expression is_even(4.4)
to work the compiler can't find any is_even
that takes a double
. And so it produced error. You can confirm this by overloading this function template with an ordinary function as shown below:
template<class T, class = std::enable_if_t<std::is_integral_v<T>>>
bool is_even(T value)
{
return ((value % 2) == 0);
}
//compiler will find this definition now and no error will be produced
bool is_even(double d)
{
return ((static_cast<int>(d) % 2) == 0);
}
Now for the call expression is_even(4.4)
the compiler finds the overloaded is_even
and hence produces no error.
Summary
The error that you're getting is not the result of SFINAE, instead it is due to the fact that the for the expression is_even(4.4)
to work, we need the definition of a function that takes a double
.
Upvotes: 1