問(wèn)題描述
在 C++ 中,返回類(lèi)型是否被視為函數(shù)簽名的一部分?不允許重載,只修改返回類(lèi)型.
普通函數(shù)的簽名中不包括返回類(lèi)型.
(注意:我已經(jīng)重寫(xiě)了這個(gè)答案,下面的評(píng)論不適用于這次修訂——詳情請(qǐng)參見(jiàn)編輯歷史).>
簡(jiǎn)介
然而,標(biāo)準(zhǔn)中關(guān)于函數(shù)和函數(shù)聲明的問(wèn)題很復(fù)雜.有兩層必須考慮:
- 聲明
- 實(shí)體
所謂的函數(shù)聲明可以聲明一個(gè)函數(shù)實(shí)體或一個(gè)模板實(shí)體.如果聲明了一個(gè)函數(shù)實(shí)體,那么您要么必須對(duì)函數(shù)模板(指定所有參數(shù))進(jìn)行顯式特化,要么必須聲明一個(gè)普通函數(shù).如果聲明了模板實(shí)體,則您聲明的是主函數(shù)模板,或未指定某些參數(shù)的顯式特化.(這與對(duì)象聲明"和對(duì)象或引用的關(guān)系非常相似:前者可以聲明一個(gè)對(duì)象或一個(gè)引用.因此對(duì)象聲明不一定聲明一個(gè)對(duì)象!).
標(biāo)準(zhǔn)在1.3.10
中定義了一個(gè)函數(shù)的簽名,包括以下內(nèi)容:
其參數(shù)的類(lèi)型,如果函數(shù)是類(lèi)成員,函數(shù)本身和聲明成員函數(shù)的類(lèi)的 cv- 限定符(如果有).函數(shù)模板特化的簽名包括其模板參數(shù)的類(lèi)型.(14.5.5.1)
它在這個(gè)定義中缺少返回類(lèi)型,它是函數(shù)模板特化簽名的一部分(即聲明一個(gè)函數(shù)是模板特化的函數(shù)聲明),如所指出的14.5.5.1
(最近的 C++0x 工作文件修復(fù)了這個(gè)問(wèn)題,也提到了 1.3.10
中的返回類(lèi)型):
函數(shù)模板特化的簽名由函數(shù)模板的簽名和實(shí)際的模板參數(shù)(無(wú)論是明確指定的還是推導(dǎo)的)組成.
函數(shù)模板的簽名由函數(shù)簽名、返回類(lèi)型和模板參數(shù)列表組成.
那么簽名到底包含什么?
因此,當(dāng)我們?cè)儐?wèn)函數(shù)的簽名時(shí),我們必須給出兩個(gè)答案:
- 對(duì)于函數(shù)模板的特化函數(shù),簽名包括返回類(lèi)型.
- 對(duì)于非特化函數(shù),返回類(lèi)型不是簽名的一部分.
但是請(qǐng)注意,無(wú)論如何,返回類(lèi)型是函數(shù)類(lèi)型的重要組成部分.也就是說(shuō),以下內(nèi)容無(wú)效:
void f();int (*pf)() = &f;//不同種類(lèi)!
如果只有返回類(lèi)型不同,重載何時(shí)無(wú)效?
主要編譯器目前拒絕以下代碼:
int f();雙 f();//無(wú)效的
但接受以下代碼:
templateint f();模板雙 f();//無(wú)效的?
然而,標(biāo)準(zhǔn)確實(shí)禁止只在返回類(lèi)型上不同的函數(shù)聲明(定義重載何時(shí)有效,何時(shí)無(wú)效).它沒(méi)有準(zhǔn)確定義僅因返回類(lèi)型而不同"的內(nèi)容.意思是,不過(guò).
標(biāo)準(zhǔn)段落引用:
- 何時(shí)可以重載函數(shù)聲明:
13.1
- 什么是函數(shù)聲明:
7/2
和7/5
- 函數(shù)模板/特化的簽名是什么:
14.5.5.1
作為參考,這里是最新的 C++0x 草案 n3000 關(guān)于簽名"的說(shuō)明.在 1.3.11
中,它對(duì)不同類(lèi)型實(shí)體的覆蓋要完整得多:
函數(shù)的名稱(chēng)和參數(shù)類(lèi)型列表 (8.3.5),以及它所屬的類(lèi)或命名空間.如果函數(shù)或函數(shù)模板是類(lèi)成員,則其簽名還包括函數(shù)或函數(shù)模板本身的 cv 限定符(如果有)和 ref 限定符(如果有).函數(shù)模板的簽名還包括其返回類(lèi)型和模板參數(shù)列表.函數(shù)模板特化的簽名包括其特化的模板的簽名及其模板參數(shù)(無(wú)論是顯式指定還是推導(dǎo)).[ 注意:簽名用作名稱(chēng)修改和鏈接的基礎(chǔ).— 尾注 ]
In C++, is the return type considered part of the function signature? and no overloading is allowed with just return type modified.
Normal functions do not include the return type in their signature.
(note: i've rewritten this answer, and the comments below don't apply to this revision - see the edit-history for details).
Introduction
However, the matter about functions and function declarations in the Standard is complicated. There are two layers that have to be considered:
- Declarations
- Entities
The so-called function declaration may declare a function entity or a template entity. If a function entity is declared, then you either have to do with an explicit specialization of a function template (with all arguments specified), or a declaration of an ordinary function. If a template entity is declared, then you are declaring a primary function template, or an explicit specialization where some arguments are not specified. (This is very similar to the relation of "object declaration" and objects or references: The former may declare either an object or a reference. So an object declaration may not necessarily declare an object!).
The Standard defines the signature of a function to include the following at 1.3.10
:
The types of its parameters and, if the function is a class member, the cv- qualifiers (if any) on the function itself and the class in which the member function is declared. The signature of a function template specialization includes the types of its template arguments. (14.5.5.1)
It's missing the return type in this definition, which is part of the signature of a function template specialization (i.e a function declaration that declares a function which is a specialization of a template), as pointed out by 14.5.5.1
(recent C++0x working papers fixed that already to mention the return type in 1.3.10
too):
The signature of a function template specialization consists of the signature of the function template and of the actual template arguments (whether explicitly specified or deduced).
The signature of a function template consists of its function signature, its return type and its template parameter list.
So what exactly does a signature contain, again?
So, when we ask about the signature of a function, we have to give two answers:
- For functions that are specializations of function templates, the signature includes the return type.
- For functions that are not specializations, the return type is not part of the signature.
Notice, however, that the return type, in any case, is a significant part of the type of a function. That is, the following is not valid:
void f();
int (*pf)() = &f; // different types!
When is an overload invalid if only the return type differs?
Major compilers currently reject the following code:
int f();
double f(); // invalid
But accept the following code:
template<typename T> int f();
template<typename T> double f(); // invalid?
However, the Standard does forbid a function declaration that only differs in the return type (when defining when an overload is valid, and when not). It does not define precisely what "differs only by return type" means, though.
Standard paragraph references:
- When can a function declaration be overloaded:
13.1
- What is a function declaration:
7/2
and7/5
- What is the signature of a function template/specialization:
14.5.5.1
For reference, here is what the most recent C++0x draft n3000 says about "signature" in 1.3.11
, which is much more complete in its coverage of the different type of entities:
the name and the parameter type list (8.3.5) of a function, as well as the class or namespace of which it is a member. If a function or function template is a class member its signature additionally includes the cv-quali?ers (if any) and the ref-quali?er (if any) on the function or function template itself. The signature of a function template additionally includes its return type and its template parameter list. The signature of a function template specialization includes the signature of the template of which it is a specialization and its template arguments (whether explicitly speci?ed or deduced). [ Note: Signatures are used as a basis for name mangling and linking. — end note ]
這篇關(guān)于返回類(lèi)型是函數(shù)簽名的一部分嗎?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!