The title is quoted from this SO answer. It is discussing using SFINAE to detect the existence of a member function with the given signature and points out a failing of the method in the accepted answer when dealing with inherited member functions. In particular, the explanation given is as follows
If you are not already wise to this gotcha, then a look at of the definition of
std::shared_ptr<T>
in the header will shed light. In that implementation,std::shared_ptr<T>
is derived from a base class from which it inheritsoperator*() const
. So the template instantiationSFINAE<U, &U::operator*>
that constitutes "finding" the operator forU = std::shared_ptr<T>
will not happen, becausestd::shared_ptr<T>
has nooperator*()
in its own right and template instantiation does not "do inheritance".This snag does not affect the well-known SFINAE approach, using "The sizeof() Trick", for detecting merely whether T has some member function mf (see e.g. this answer and comments).
Using the terminology from the answer, what is the difference between using T::mf
as a template argument to instantiate a type vs having the compiler determine it through a template function argument deduction? What does "template instantiation does not do inheritance" mean? And lastly, why doesn't this affect simply checking for existence of a member, like here?