Is this program badly formed despite SFINAE?

template <typename T> void f() { return 0; // returning value from function returning `void` } int main() { // Not instantiating or calling any f<T>() } 

In the comments on this answer, David claims that a function template that contains a semantic error and is not created leads to a bad form of the program:

Whether the template is used or not, the program is poorly formed even without an instance, but the compiler is not required to diagnose it.

And vice versa, I’m sure that SFINAE, as well as preventing type subtraction and, therefore, creating a function template in [C++11: 14.8.2/8] , allows the program to remain well formed. however, I cannot find text in this standard paragraph that explicitly speaks of this.

Who is right?


Wikipedia, which I will not consider authoritative for this issue, speaks of a slightly different case:

[..] SFINAE was introduced to avoid creating poorly formed programs when unrelated template declarations were detected [..]

(my emphasis)

+2
source share
2 answers

The program is poorly formed according to 14.6 / 8:

If a valid specialization cannot be created for the template definition and this template is not created, the template definition is poorly formed, diagnostics are not required.

That is, whether you are creating an instance of the template or not, the definition of the template is poorly formed, since there is no possible instance that will be successful.

Note that this is completely unrelated to SFINAE: Failure Substitution is not an error, it is part of the lookup process and never takes into account the contents of the template.

+9
source

Reading more carefully, this standard passage reads:

If the substitution results in an invalid type or expression, the deduction type is not performed. An invalid type or expression is one that would be poorly formed if it were written using substituted arguments. [..]

return 0 not an expression, so SFINAE is not applicable.

The passage continues:

Only invalid types and expressions in the immediate context of a function type and its template parameter types can lead to an output error.

return 0 has nothing to do with the type of the function or its types of template parameters, so SFINAE is still not applied.

+1
source

Source: https://habr.com/ru/post/1243095/


All Articles