template <typename T> void f() {
return 0; // returning value from function returning `void`
}
int main()
{
// Not instantiating or calling any f<T>()
}
In comments to this answer, David asserts that a function template that contains a semantic error and is not instantiated causes a program to be ill-formed:
Whether the template is used or not does not matter, the program is ill-formed even with no instantiation but the compiler is not required to diagnose it.
Conversely, I am quite sure that SFINAE, as well as preventing type deduction and therefore instantiation of the function template per [C++11: 14.8.2/8]
, allows the program to remain well-formed. however I cannot find any text in this standard paragraph that explicitly says so.
Who is correct?
Wikipedia, which I shall not consider authoritative for this question, says about a slightly different case:
[..] SFINAE was introduced to avoid creating ill-formed programs when unrelated template declarations were visible [..]
(emphasis mine)
The program is ill-formed as per 14.6/8:
If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required.
That is whether you instantiate the template or not, the template definition is ill-formed as there is no possible instantiation that will succeed.
Note that this is completely unrelated to SFINAE: Substitution Failure is not an Error is part of the substitution process, and never takes into account the contents of the template.
Reading more closely, that standard passage says:
If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is one that would be ill-formed if written using the substituted arguments. [..]
return 0
is not an expression, so SFINAE does not apply.
The passage goes on:
Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure.
return 0
has nothing to do with the function type or its template parameter types, so SFINAE still does not apply.