我看了几个相关的堆栈溢出线程,如 这种模板函数重载的情况不符合我的理解
和
但似乎都没有给我我正在寻找的答案,至少不是以一种我很容易解释的方式。
我的问题归结为:从设计和技术的角度来看,为什么这样做是合法的:
#include <iostream>
using namespace std;
template<class T>
void func(){
cout << "Compiler inferred from void return value!\n";
}
template<class T>
int func(){
cout << "Compiler inferred from int return value!\n";
return 0;
}
int main(){
void (*thisFunc)()=func<int>;
int (*thatFunc)()=func<int>;
thisFunc();
thatFunc();
}
但不是这个:
#include <iostream>
using namespace std;
void func(){
cout << "You won't see this because it won't compile!\n";
}
int func(){
cout << "Nor this one!\n";
return 0;
}
int main(){
void (*thisFunc)()=func;
int (*thatFunc)()=func;
thisFunc();
thatFunc();
}
值得一提的是,如果我在初始化thisFunc和thatFunc时没有明确地给func一个任意的模板参数,那么第一个例子就不会编译。两者之间唯一的另一个区别是第一个有func的函数是一个完全无关紧要的类型,除了它显然允许我通过返回类型重载。在这种情况下,编译器甚至能够对要调用的函数进行推断,使得c ++中返回类型的函数重载的非法性对我来说有些困惑。无论如何,我猜这是一个巧妙的技巧。
编辑:最困扰我的是不一致性:在我真正考虑通过返回类型进行重载之前,我会想很长很难,但如果对某人进行“修复” 希望 通过返回类型重载是简单地添加一个无意义的模板参数或显然将函数包装在命名空间内,然后我认为C ++应该或多或少地严格关于它认为不明确的内容。是否有令人信服的理由为什么模板和命名空间需要此功能才能正常工作?例如,如果不允许模板在我的示例中消除代码歧义,那么是否有一个可行的代码无法工作的示例?我从语言设计的角度提出要求,而不是编译器合规性的观点。