I have the following sample code:
class Serializable {};
class MyData : public Serializable {};
void GetData( Serializable& ) {}
template<typename T>
void GetData( T& data )
{
std::istringstream s{"test"};
s >> data;
}
int main()
{
MyData d;
GetData(d);
}
Based on overload resolution rules, the non-template version should be preferred because the base class is of type Serializable
. However, I expect SFINAE to kick in when there are errors in the template version when it is instantiated for overload resolution (because if the >> operator is not defined for a type, it should not be considered).
Why is it still failing even though the template won't be used?
Not quite. [over.match.best]:
That means that only if the deduced specialization of the function template necessitates a conversion that isn't better than the conversion that the normal function necessitates, your rule applies. And the binding of
d
toSerializable&
is a worse conversion than the binding of d toMyData&
(which is the type of the parameter of the specialization), [over.ics.ref]:SFINAE doesn't apply for the content of a function template. [temp.deduct]/8:
Hence the deduced specialization of the function template is indeed chosen, and causes a compiler error while instantiating its definition.