考虑:
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的函数中有一个非法的返回语句,上面的代码仍将通过.
你这样做:
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语句,函数返回'无效"
虽然程序仍然格式不正确,但编译器选择不诊断语义错误(这是它的特权)因为你实际上从未实际实例化该函数.
这是一个实施质量问题.标准的特别引用是:
14.6/8 [...]如果无法为模板定义生成有效的专业化,并且未实例化该模板,则模板定义格式错误,无需诊断.[...]
也就是说,您的程序生成错误,因为该模板不能用于生成任何有效的特化,但编译器不需要诊断它.当您稍后实例化模板时,编译器必须生成特化,专业化无效并且编译器会抱怨.
您不会在模板定义中出现错误,因为编译器遵循无诊断所需的路径,即忽略问题,直到它在实例化中不再忽略它.