C++ 尽管有SFINAE,该计划是否形式不良? template void f(){ 返回0;//从返回'void'的函数返回值` } int main() { //不实例化或调用任何f() }

C++ 尽管有SFINAE,该计划是否形式不良? template void f(){ 返回0;//从返回'void'的函数返回值` } int main() { //不实例化或调用任何f() },c++,language-lawyer,sfinae,C++,Language Lawyer,Sfinae,在对的注释中,断言包含语义错误且未实例化的函数模板会导致程序格式错误: 无论是否使用模板都无关紧要,即使没有实例化,程序的格式也不正确,但不需要编译器对其进行诊断 相反,我非常确信SFINAE,以及防止类型推断,从而根据[C++11:14.8.2/8]实例化函数模板,允许程序保持良好的格式。然而,我在这个标准段落中找不到任何明确说明这一点的文本 谁是对的? [P>维基百科,我不认为这个问题有权威性,说了一个稍微不同的例子: [..]SFINAE的引入是为了避免在不相关的模板声明可见时创建格式错

在对的注释中,断言包含语义错误且未实例化的函数模板会导致程序格式错误:

无论是否使用模板都无关紧要,即使没有实例化,程序的格式也不正确,但不需要编译器对其进行诊断

相反,我非常确信SFINAE,以及防止类型推断,从而根据
[C++11:14.8.2/8]
实例化函数模板,允许程序保持良好的格式。然而,我在这个标准段落中找不到任何明确说明这一点的文本

谁是对的?


[P>维基百科,我不认为这个问题有权威性,说了一个稍微不同的例子:

[..]SFINAE的引入是为了避免在不相关的模板声明可见时创建格式错误的程序[/strong>[..]


(我的重点)

仔细阅读,标准段落说:

如果替换导致无效的类型或表达式,则类型推断将失败。无效类型或表达式是使用替换参数编写时格式不正确的类型或表达式。[……]

返回0
不是表达式,因此SFINAE不适用

文章接着说:

只有函数类型及其模板参数类型的直接上下文中的无效类型和表达式才能导致推断失败


返回0
与函数类型或其模板参数类型无关,因此SFINAE仍然不适用。

根据14.6/8,程序格式不正确:

如果无法为模板定义生成有效的专门化,并且该模板未实例化,则模板定义的格式不正确,不需要诊断

也就是说,无论是否实例化模板,模板定义的格式都不正确,因为没有可能成功的实例化


请注意,这与SFINAE完全无关:替换失败不是错误,而是替换过程的一部分,并且从不考虑模板的内容。

我看不出SFINAE与此有什么关系。程序中的错误与模板参数无关。@KerrekSB:你说得对;这就是答案。@DavidRodríguez dribeas:不太“有趣”-当我们开始在对另一个答案的评论中讨论这个问题时,答案没有显示在我的屏幕上。@LightnessRacesinOrbit:这一定是页面中的一个小故障,在我写评论之前,我给出了答案:)如果我每十秒钟按F5一次,这是不是很糟糕-SAs it说,不需要诊断,但如果编译器更努力地诊断这些事情,那就太好了。@bames53:编译器倾向于尽可能少地处理模板。在本例中,这是显而易见的,但可能还有其他模板永远不会生成有效的实例化,并且更难检测。
template <typename T> void f() {
    return 0;  // returning value from function returning `void`
}

int main()
{
    // Not instantiating or calling any f<T>()
}