尽管有SFINAE,这个节目是否格局不正确?

时间:2012-11-06 18:30:22

标签: c++ language-lawyer sfinae

template <typename T> void f() {
    return 0;  // returning value from function returning `void`
}

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

在对this answer的评论中,David断言包含语义错误但未实例化的函数模板导致程序格式错误:

  

是否使用模板并不重要,即使没有实例化,程序仍然是格式错误,但编译器不需要诊断它。

相反,我很确定SFINAE,以及防止类型推导以及每个[C++11: 14.8.2/8]的函数模板的实例化,使程序保持良好的形式。但是我在这个标准段落中找不到任何明确说明的文字。

谁是对的?


维基百科,我不会认为这个问题具有权威性,它说的是一个略有不同的案例:

  

[..]当不相关的模板声明可见时,SFINAE被引入以避免创建格式错误的程序 [...]

(强调我的)

2 个答案:

答案 0 :(得分:9)

根据14.6 / 8,该计划格式不正确:

  

如果无法为模板定义生成有效的专业化,并且未实例化该模板,则模板定义格式错误,无需诊断。

无论您是否实例化模板,模板定义都是格式错误的,因为没有可能的实例化会成功。

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

答案 1 :(得分:1)

更仔细地阅读,标准段落说:

  

如果替换导致无效的类型或表达式,则类型推导失败。如果使用替换参数写入,则无效的类型或表达式将是格式错误的。 [..]

return 0不是表达式,因此SFINAE不适用。

这段经文继续:

  

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

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