[net.lang.c++] Function Overloading

rmarti@sun.uucp (Bob Marti) (03/11/86)

Assume the following declarations:

	int i;

	int f(int x)
	{
		// some code
	}

	overload f;
	float f(int x)
	{
		// some code
	}


and the following call of function f:

	(void) f(i);

Which function will be called, the one corresponding to int f(int x) or the
one corresponding to float f(int x)?

Bob Marti, Sun Microsystems
ARPA: rmarti@sun.arpa
UUCP: ... {decvax, hplabs, ihnp4, seismo, ucbvax}!sun!rmarti

bs@alice.UucP (Bjarne Stroustrup) (03/13/86)

> Path: alice!allegra!ulysses!bellcore!decvax!decwrl!sun!rmarti
> From: rmarti@sun.uucp (Bob Marti)
> Subject: Function Overloading
> Organization: Sun Microsystems, Inc.

(The following is slightly edited to save space)

> Assume the following declarations:
> 
> 	int f(int x) { /* some code */ }
> 	overload f;
> 	float f(int x) { /* some code */ }
> 
> and the following call of function f:
> 
> 	int i;
> 	(void) f(i);
> 
> Which function will be called, the one corresponding to int f(int x) or the
> one corresponding to float f(int x)?

Firstly, this example will not compile; you get:

"", line 3: error:  f redefined as overloaded

The overload declaration for a name must occur before the first declaration
of a function with that name. I believe that this restriction avoids
unnecessary subtleties. So you might try this:

	overload f;
 	int f(int x) { /* some code */ }
	float f(int x) { /* some code */ }

This will not compile either; you get:

"", line 3: error: two different return value types for overloaded f():  int  and  float 

C++ distinguishes overloaded functions based on the argument types only
(and never from context based on the return value). This implies that the
problem you appear to have in mind cannot occur. Overloaded function
resolution in C++ is a strictly bottom up affair (one function or operator
at a time). I beleive this makes it inherently simpler, faster to compile,
and easier to understand than, for example, Ada's rules.

What you ``lose'' in this scheme is the ability to have the declarations
above and then say

	int i = f(2);	// call ``int f(int)''		// this is not C++
	int f = f(2);	// call ``float f(int)''	// this is not C++

and then having to wonder about this one

	(void) f(2);	// which f?

	- Bjarne Stroustrup (AT&T Bell Labs, Murray Hill)

dmiruke@isis.UUCP (Dataram Miruke) (03/13/86)

> Assume the following declarations:
> 
> 	int i;
> 
> 	int f(int x)
> 	{
> 		// some code
> 	}
> 
> 	overload f;
> 	float f(int x)
> 	{
> 		// some code
> 	}
> 
> 
> and the following call of function f:
> 
> 	(void) f(i);
> 
> Which function will be called, the one corresponding to int f(int x) or the
> one corresponding to float f(int x)?
> 
> Bob Marti, Sun Microsystems
> ARPA: rmarti@sun.arpa
> UUCP: ... {decvax, hplabs, ihnp4, seismo, ucbvax}!sun!rmarti

	I tried to compile the code fragmnent below and seems like our CC does
not like what it sees. this is what it returns which probably makes sense
considering what bs specifies about the function overloading in his book.

CC +L /u2/dmiruke/x.c:
"/u2/dmiruke/x.c", line 11: error:  f redefined as overloaded
"/u2/dmiruke/x.c", line 13: warning: overloaded  f() defined without being previously declared
1 error
 (But then the CC version that we have is a pre-release version so.....!)

See page 290-291, in "The C++ Programming Language". In particular bs says ...

	" When that name is used (overloaded name), the correct function is
selected by comparing the types of the actual arguments with the formal
argument types.
	Finding which function to call is done in three steps :
 1. Look for an exact match and use it if found.
 2. Look for a match using the standard conventions and use any one if found.
 3. Look for a match using user-defined conversions. If a unique set of
    conversions is found then use it.
    ....... "

    -- though the term "any one" in (2) above bothers me a bit. what if there
are more than one matches? how does the selection proceeds then? Maybe bs could
make it a bit clearer. below is the code fragment.
	I believe that since the compiler uses the fact that the proper
selection amongst the overloaded functions is done with the help of argument
types it is important for the compiler to be able to differentiate between the 
arguments at least to some extent. May be in the new version of c++ bs should
also consider the return type of the functions.


#include	<stream.h>

int  z = 5 ;

int f (int x)
{ cout << "from float f(int x) : " << x << "\n" ;
  return x ;
}

overload f;

float f (int x)
{ cout << "from float f(int x) : " << x << "\n" ;
  return (float) x ;
}

main ()
{
 (void) f(z) ;
 cout << "I love c++ except for what you are asking above " << "\n" ;
 }

PS : (To bs specifically) : Have you considered adding the facility to let the
programmer define the new operators, rather than restricting him/er to use the
existing operators.
 	How about having a discussion on the net.lang.c++ about various
additions that people would like to see in the language.
						- Dattaram T. Miruke
						  CSNET : dmiruke@udenva
							  dmiruke@isis
						  VOICE : 744-6045.