Home >Backend Development >C++ >Why Does SFINAE Fail in Return Types but Succeed with Template Parameters?
SFINAE in Return Types vs. Template Parameters
Suppose we have a function template foo that distinguishes between integral and floating-point numbers:
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> auto foo(T) -> void; template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type> auto foo(T) -> void;
However, this code fails with an error when called with a double value:
foo(3.4); // Error: no matching function for call to 'foo(double)'
Why does this approach fail?
In this case, SFINAE is used to conditionally define the return type of foo. However, this violates the rules of function template overloading, which do not consider default template arguments. Consequently, the compiler treats both foo templates as the same function with the same signature.
Alternative Approach using Expression Referring Template Parameters
To resolve this issue, we can instead use expression referring template parameters in the return type:
template<typename T> auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type; template<typename T> auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type;
With this modification, the expression std::enable_if becomes part of the function signature, allowing SFINAE to differentiate between the two foo templates.
Therefore, the second version of foo works correctly, while the first version triggers an error.
The above is the detailed content of Why Does SFINAE Fail in Return Types but Succeed with Template Parameters?. For more information, please follow other related articles on the PHP Chinese website!