我注意到用于区分唯一模板函数的签名与用于区分唯一函数(包括那些从模板函数实例化的函数)的签名之间存在不对称性.
特别是,仅由返回类型不同的模板函数被认为是唯一的,而仅由返回类型不同的函数被认为是冗余的.
因此,我有一个相应的问题,关于如何在实例化之间消除仅由返回类型不同的函数模板之间的歧义:
#include <iostream>
template<typename T>
long foo(T)
{
std::cout << "long" << std::endl;
return 0;
}
template<typename T>
char foo(T)
{
std::cout << "char" << std::endl;
return '\0';
}
int main()
{
double d = 0.0;
long n = foo(d); // <- Ambiguous: How to specify the template function to use?
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,模板函数的实例化foo是模糊的,因为我刚才提到的不对称性.两个模板函数定义的存在是合法的,但实例化是非法的,即使返回类型在同一行代码中指定.
我纯粹是出于理论学习的目的而提出这个问题.也许这种代码构造在现实生活中会成为糟糕设计的标志.也许它永远不会出现在现实生活中.此外,我可以通过更改模板定义(或通过进行其他更改)来设想克服此问题的不同方法.
但是,我仍然想知道,如果保持模板定义不变,可以在实例化时消除这两个模板函数之间的歧义.
与为什么将函数转换为除返回类型之外相同的函数类型失败相关?,我想以更全面的方式理解函数类型和函数签名之间的区别.
例如,该类型的函数的通常必须与函数指针处理时考虑,并且函数的类型包括该函数的返回类型.
但是,正如Mike Seymour对上述相关问题的回答所述,函数的签名与函数的类型不同.签名当然用于从潜在的重载函数中消除歧义(注意函数的返回类型在识别唯一函数中不起作用).但是,我现在想了解功能签名与功能类型的相关性和重要性.在我看来,C++中函数签名的唯一目的是在重载决策期间识别过载集中的重载候选和/或唯一函数.
我对么?重载解析是C++中函数签名的唯一目的吗?或除了(或仅间接相关)重载决议之外,还有其他功能签名用途/应用吗?
附录为清楚起见,请注意我特别想了解功能签名的目的与功能类型之间的区别.即,我知道函数类型的使用和编译器/链接器的调用约定的实现都需要函数类型.但是,调用约定仅在重载解析完成后才有意义.我在这里问,具体来说,函数签名的唯一目的(与类型相反)是否用于重载解析.