当前位置:  开发笔记 > 编程语言 > 正文

返回类型是函数签名的一部分吗?

如何解决《返回类型是函数签名的一部分吗?》经验,为你挑选了2个好方法。

在C++中,返回类型是否被认为是函数签名的一部分?只修改了返回类型,不允许重载.



1> Johannes Sch..:

普通函数的签名中不包含返回类型.

(注意:我已经重写了这个答案,下面的评论不适用于此修订版 - 有关详细信息,请参阅编辑历史记录).

介绍

但是,标准中关于函数和函数声明的问题很复杂.必须考虑两个层次:

声明

实体

所谓的函数声明可以声明函数实体或模板实体.如果声明了一个函数实体,那么您要么必须使用函数模板的显式特化(指定所有参数),要么使用普通函数的声明.如果声明了模板实体,那么您将声明主函数模板,或者未指定某些参数的显式特化.(这与"对象声明"和对象或引用的关系非常相似:前者可以声明对象或引用.因此对象声明可能不一定声明对象!).

标准定义了函数的签名,包括以下内容1.3.10:

它的参数类型,如果函数是类成员,则函数本身的cv限定符(如果有)和声明成员函数的类.函数模板特化的签名包括其模板参数的类型.(14.5.5.1)

它缺少此定义中的返回类型,它函数模板特化的签名的一部分(即声明函数是模板特化的函数声明),如14.5.5.1(最近的C++ 0x工作文件所指出)修复了那里已经提到的返回类型1.3.10):

函数模板特化的签名包括函数模板的签名和实际模板参数的签名(无论是明确指定还是推导).

函数模板的签名由其函数签名,返回类型和模板参数列表组成.

那么签名究竟包含什么呢?

所以,当我们询问函数的签名时,我们必须给出两个答案:

对于作为函数模板特化的函数,签名包括返回类型.

对于非特化的函数,返回类型不是签名的一部分.

但请注意,返回类型在任何情况下都是函数类型的重要部分.也就是说,以下内容无效:

void f();
int (*pf)() = &f; // different types!

如果只有返回类型不同,何时重载无效?

主要编译器目前拒绝以下代码:

int f();
double f(); // invalid

但是接受以下代码:

template int f();
template double f(); // invalid?

但是,标准确实禁止函数声明,该函数声明仅在返回类型中有所不同(定义何时重载有效,何时不是).但是,它没有准确定义"只有返回类型不同"的含义.


标准段落参考:

何时可以重载函数声明: 13.1

什么是函数声明:7/27/5

功能模板/专业化的签名是什么: 14.5.5.1

作为参考,这里是最新的C++ 0x草案n3000关于"签名"的内容1.3.11,它在不同类型的实体的覆盖范围内更为完整:

函数的名称和参数类型列表(8.3.5),以及它所属的类或命名空间.如果函数或函数模板是类成员,则其签名还包括函数或函数模板本身的cv-quali firs(如果有)和ref-quali fi er(如果有的话).函数模板的签名还包括其返回类型和模板参数列表.函数模板特化的签名包括作为特化的模板的签名及其模板参数(无论是明确指定还是推导).[注意:签名用作名称修改和链接的基础. - 结束说明]



2> Nicola Bonel..:

这取决于函数是否是函数模板.

C++模板 - 完整指南中,Jusuttis提供了与C++标准中给出的不同的定义,但具有相同的结果:

我们将函数的签名定义为以下信息:

    函数的不合格名称

    名称命名空间范围,如果名称具有内部链接,则为声明名称的转换单元

    功能的const,volatileconst volatile资格

    函数参数的类型

    如果函数是从函数模板生成的,则返回类型

    模板的参数模板参数,如果函数是从一个函数模板生成

正如litb建议的那样,值得澄清为什么返回类型是模板函数签名的一部分.

如果程序具有不同的签名,则它们可以共存于程序中.

.也就是说,如果返回类型是模板参数:

template 
T foo(int a)
{return T();}

它可以实例化两个仅在返回类型上有所不同的函数:

foo(0);
foo(0);

不仅如此:正如litb正确报告的那样,也可以重载两个模板函数,这些函数仅在返回类型上有所不同,即使返回类型不是依赖名称.这是他的例子:

template int foo(T)
{}

template bool foo(T)
{}

// at the instantiation point it is necessary to specify the cast
// in order not to face ambiguous overload

((int(*)(char))foo)('a'); 

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有