![](/img/trans.png)
[英]Are type aliases used as type of function parameter part of the function signature?
[英]Is the return type part of the function signature?
在C ++中,返回类型是否被视为函数签名的一部分? 并且仅修改返回类型就不允许重载。
普通函数的签名中不包含返回类型。
( 注意 :我已经重写了此答案,并且以下注释不适用于此修订版-有关详细信息,请参见编辑历史记录。)
但是,标准中有关函数和函数声明的问题很复杂。 必须考虑两层:
所谓的功能声明可以声明功能实体或模板实体。 如果声明了一个功能实体,那么您要么必须要明确指定功能模板(指定所有参数),要么要声明一个普通功能。 如果声明了模板实体,那么您将声明一个主函数模板,或者未指定某些参数的显式专门化。 (这与“对象声明”与对象或引用的关系非常相似:前者可以声明对象或引用。因此, 对象声明不一定必须声明对象!)。
标准在1.3.10
定义了函数的签名,以包括以下1.3.10
:
参数的类型,如果函数是类成员,则函数本身的cv限定词(如果有)以及声明该成员函数的类。 功能模板特化的签名包括其模板参数的类型。 (14.5.5.1)
如14.5.5.1
(最近的C ++)所指出的,它缺少此定义中的返回类型,该类型是函数模板特化(即声明函数的功能声明,该函数是模板的特化)的签名的一部分。 0x工作文件已修复在1.3.10
中已经提到返回类型的1.3.10
):
功能模板专业化的签名由功能模板的签名和实际模板参数(无论是显式指定还是推论)组成。
功能模板的签名由其功能签名,返回类型和模板参数列表组成。
因此,当我们询问函数的签名时,我们必须给出两个答案:
但是请注意,无论如何,返回类型都是函数类型的重要组成部分。 也就是说,以下无效:
void f();
int (*pf)() = &f; // different types!
当前,主要的编译器拒绝以下代码:
int f();
double f(); // invalid
但是接受以下代码:
template<typename T> int f();
template<typename T> double f(); // invalid?
但是, 标准确实禁止仅在返回类型上有所不同的函数声明 (当定义重载何时有效,何时无效)。 但是,它没有精确定义“仅按返回类型不同”的含义。
标准段落参考:
13.1
7/2
和7/5
14.5.5.1
作为参考,这里是最新的C ++ 0x N3000草案说,大约在“签名” 1.3.11
,这是其在不同类型的实体的覆盖范围更加完整:
函数的名称和参数类型列表(8.3.5),以及该函数所属的类或名称空间。 如果功能或功能模板是类成员,则其签名还包括功能或功能模板本身上的cv限定符(如果有)和ref限定符(如果有)。 功能模板的签名还包括其返回类型和模板参数列表。 功能模板特化的签名包括为其特化的模板的签名及其模板自变量(无论是明确指定还是推导)。 [注意:签名用作名称处理和链接的基础。 —尾注]
这取决于功能是否为功能模板 。
在C ++模板-完整指南中 ,Jusuttis提供了与C ++标准中给定的定义不同的定义,但具有同等的结果:
我们将函数的签名定义为以下信息:
const
, volatile
或const volatile
限定 正如litb所建议的,有必要澄清为什么返回类型是模板函数签名的一部分。
如果函数具有不同的签名,则它们可以共存于程序中。
。 也就是说,如果返回类型是模板参数:
template <typename T>
T foo(int a)
{return T();}
可以实例化两个仅在返回类型上不同的函数:
foo<int>(0);
foo<char>(0);
不仅:正如litb所正确报道的那样 ,还可以重载两个模板函数,即使返回类型不是从属名称,它们也仅在返回类型上有所不同。 这是他的例子:
template<class T> int foo(T)
{}
template<class T> bool foo(T)
{}
// at the instantiation point it is necessary to specify the cast
// in order not to face ambiguous overload
((int(*)(char))foo<char>)('a');
它们是该类型的一部分,您可以根据仅返回类型不同的函数指针类型来重载函数:
int IntFunc() { return 0; }
char CharFunc() { return 0; }
void FuncFunc(int(*func)()) { cout << "int\n"; }
void FuncFunc(char(*func)()) { cout << "char\n"; }
int main()
{
FuncFunc(&IntFunc); // calls void FuncFunc(int_func func)
FuncFunc(&CharFunc); // calls void FuncFunc(char_func func)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.