What does it mean when one says something is SFINAE-friendly?

When it allows substitution failure without hard error (as static_assert).

for example

template <typename T>
void call_f(const T& t)
{
    t.f();
}

The function is declared for all T, even those which don’t have f, so you cannot do SFINAE on call_f<WithoutF> as the method does exist. (Demo of non compiling code).

With following change:

template <typename T>
auto call_f(const T& t) ->decltype(t.f(), void())
{
    t.f();
}

The method exists only for valid T.
so you can use SFINAE as

template<typename T>
auto call_f_if_available_impl(const T& t, int) -> decltype(call_f(t))
{
    call_f(t);
}

template<typename T>
auto call_f_if_available_impl(const T& t, ...)
{
    // Do nothing;
}

 template<typename T>
 auto call_f_if_available(const T& t)
 {
    call_f_if_available_impl(t, 0);
 }

Note the int = 0 and ... is to order the overload.
Demo

An other case is when the template add special parameter to apply SFINAE for specialization:

template <typename T, typename Enabler = void> struct S;

And then

// Specialization only available for T which respect the traits.
template <typename T>
struct S<T, std::enable_if_t<my_type_trait<T>::value>>
{
};

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)