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

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

对此答案的评论中,David断言包含语义错误且未实例化的函数模板会导致程序格式错误:

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

相反,我很确定 SFINAE 以及防止类型推断和因此函数模板 per 的实例化[C++11: 14.8.2/8],允许程序保持格式良好。但是,我在此标准段落中找不到任何明确说明的文本。

谁是正确的?


维基百科,我不认为它对这个问题具有权威性,它谈到了一个稍微不同的情况:

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

(强调我的)

4

2 回答 2

9

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

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

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

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

于 2012-11-06T18:39:58.920 回答
1

仔细阅读,该标准段落说:

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

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

段落继续:

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

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

于 2012-11-06T18:34:19.343 回答