Is part of the return type a function signature?

In C ++, is the return type considered part of the function signature? and overloading is not allowed with changing the type of the return type.

+57
c ++ function
Nov 14 '08 at 13:17
source share
3 answers

Normal functions do not include the return type in their signature.

(note: I rewrote this answer, and the comments below do not apply to this revision - see the change history for details).

Introduction

However, the issue of functions and function declarations in the Standard is complex. Two layers must be considered:

  • ads
  • Entities

A so-called function declaration can declare a function object or a template object. If a function object is declared, then you must either deal with the explicit specialization of the function template (with all the arguments specified), or with the declaration of a regular function. If the template object is declared, then you declare the template of the primary function or an explicit specialization in which some arguments are not specified. (This is very similar to the relationship between “declaring an object” and objects or links: the former may declare either an object or a link. Thus, declaring an object may not necessarily declare an object!).

The standard defines a function signature, which includes the following in 1.3.10 :

The types of its parameters and, if the function is a member of the class, cv-qualifiers (if any) for the function itself and the class in which the member function is declared. The signature of a template specialization includes types of template arguments. (14.5.5.1)

This definition 14.5.5.1 return value type, which is part of the signature of a specialized function (i.e., declaring a function declaring a function that is a specialization of the template), as indicated in 14.5.5.1 (recent C ++ 0x working documents fixed, what type to already mention return to 1.3.10 too):

The signature of the specialized function of the template consists of the signature of the function template and the actual arguments of the template (explicit or implicit).

The signature of a function template consists of its function signature, its return type, and a list of template parameters.

So what exactly does the signature contain, again?

So, when we ask about the function signature, we have to give two answers:

  • For functions that are specializations of function templates, the signature includes a return type.
  • For functions that are not specializations, the return type is not part of the signature.

Note, however, that the return type is in any case a significant part of the function type. That is, the following is unacceptable:

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

When is underloading unacceptable if only the return type is different?

Currently, major compilers 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 prohibits declaring a function that differs only from the type of return (when determining when an overload is valid and when not). It does not define exactly what “differs only by the inverse type”.




Standard paragraph references:

  • When a function declaration may be overloaded: 13.1
  • What is function announcement: 7/2 and 7/5
  • What is a template signature / function specialization: 14.5.5.1

For reference, here is what the latest C ++ 0x n3000 project about the "signature" in 1.3.11 , which is much more complete in its scope of various types of objects:

the name and list of parameter types (8.3.5) of the function, as well as the class or namespace of which it is a member. If a function or function template is a member of a class, its signature additionally includes cv-qualiers (if any) and ref-quali fi (if any) in the function itself or in the function template. The signature of the function template further includes its return type and a list of template parameters. The signature of the specialized function of the template includes the signature of the template for which it is a specialization and its template arguments (explicitly or specified). [Note. Signatures are used as the basis for name manipulation and binding. - final note]

+77
Nov 14 '08 at 13:20
source share

It depends on whether the function is a function template or not.

The C ++ Templates are complete manuals ; Jusuttis provides a different definition given in the C ++ standard, but with equivalent consequences:

We define the function signature as the following information:

  • Unqualified function name
  • The class or namespace of this name, and if the name has an internal relationship, the translation unit in which the name is declared
  • Qualification of const , volatile or const volatile functions
  • Types of Function Parameters
  • its return type if the function is created from the function template
  • Template parameters and template arguments if the function is generated from the function template

As litb suggested, it's worth finding out why the return type is part of the signature of the template function.

Functions can coexist in a program if they have different signatures.

. However, if the return type is a template parameter:

 template <typename T> T foo(int a) {return T();} 

It is possible to create two functions that differ only in the return type:

 foo<int>(0); foo<char>(0); 

Not only: as litb said correctly , it is also possible to overload two template functions that differ only in the return type, even if the return type is not a dependent name. Here is an example of it:

 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'); 
+9
Nov 15 '08 at 10:29
source share

They are quite part of the type that you can overload functions based on types of function pointers that differ only in the return type:

 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) } 
+2
Nov 21 '08 at 18:11
source share



All Articles