为什么不从void函数模板返回编译器错误?

0x4*_*2D2 4 c++ templates

考虑:

void f() {
    return 5;
}
Run Code Online (Sandbox Code Playgroud)

以上会引起错误.但为什么不呢?:

template <typename = void> void f() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在用gcc-4.5.1编译.为什么使用模板会产生差异,以至于我不会因为非模板函数执行相同的非法返回语句而收到错误?我得到的唯一挫折是我无法调用函数(即f())而没有得到:

error: return-statement with a value, in function returning 'void'

但是,我能够为void函数模板定义return语句的原因是什么?

这是我的代码:

template <typename = void> void f() {
    return 0;
}

// pass

int main() {



}
Run Code Online (Sandbox Code Playgroud)

尽管在返回void的函数中有一个非法的返回语句,上面的代码仍将通过.

Kar*_*ath 10

大多数检查仅在您实例化模板时完成.

这通常是一件好事,因为代码可以使用一种模板参数正常工作,但无法使用另一种模板参数进行编译.如果您有模板重载,编译器甚至会忽略无法编译的候选项,请参阅SFINAE.

  • 这个答案有点误导:即使模板从未实例化,程序也是格式不正确的.大多数编译器在标准中使用*无诊断要求*注释并忽略该问题这一事实是一个完全不同的问题.特别是,在实例化模板之前忽略此错误没有任何价值:一旦看到定义,编译器就可以挽救并避免额外的处理成本. (4认同)

Lig*_*ica 7

这样做:

template <typename = void> void f() {
    return 0;
}

int main()
{
    f<int>();
}
Run Code Online (Sandbox Code Playgroud)

prog.cpp:在函数'void f()[with = int]':
prog.cpp:7:12:从这里实例化
prog.cpp:2:12:错误:带语句的return语句,函数返回'无效"

虽然程序仍然格式不正确,但编译器选择不诊断语义错误(这是它的特权)因为你实际上从未实际实例化该函数.


Dav*_*eas 6

这是一个实施质量问题.标准的特别引用是:

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

也就是说,您的程序生成错误,因为该模板不能用于生成任何有效的特化,但编译器不需要诊断它.当您稍后实例化模板时,编译器必须生成特化,专业化无效并且编译器会抱怨.

您不会在模板定义中出现错误,因为编译器遵循无诊断所需的路径,即忽略问题,直到它在实例化中不再忽略它.