Overloading in C++, part I
Friday, February 23, 2007
The following are the things we need to know about overloading:
What can be overloaded?
[1] Only function declarations can be overloaded; object and type declarations cannot be overloaded.
[2] Function declarations that differ only in return type cannot be overloaded.
void f();
int f(); // violation of [2]
Static members and the implicit object
[3] Member function declarations with the same name and the same parameter types cannot be overloaded if any of them is a static member function declaration.
class X
{
public:
static void f();
void f() const; // violation of [3]
void f() const volatile; // violation of [3]
};
[3.1] If there is no static member function declaration among a set of member function declarations with the same name and the same parameter types, then these member function declarations can be overloaded if they differ in the type of their implicit object parameter.
class X
{
public:
void f();
void f() const; // valid
void f() const volatile; // valid
void g() const; // violation of [3.1]
void g() const; // violation of [3.1]
};
Equivalent Parameter Declaration
[4] Function declarations that have equivalent parameter declarations declare the same function and therefore cannot be overloaded.
[4.1] Parameter declarations that differ only in the use of equivalent typedef "types" are equivalent. A typedef is not a separate type, but only a synonym for another type.
typedef int Integer;
class X
{
public:
void f( int a );
void f( Integer b ); // violation of [4.1]
};
[4.2] Enumerations are distinct types and can be used to distinguish overloaded function declarations.
enum E { SOMETHING, NOTHING };
class X
{
public:
void f( int a );
void f( E b ); // valid
};
[4.3] Parameter declarations that differ only in a pointer * versus an array [] are equivalent. That is, the array declaration is adjusted to become a pointer declaration.
class X
{
public:
void f( char* a );
void f( char b[] ); // violation of [4.3]
void f( char c[20] ); // violation of [4.3]
};
[4.4] Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type.
class X
{
public:
void f( int() );
// redeclaration of f( int() )
void f( int (*)() );
// definition of f( int() )
void f( int() ) {}
// ill-formed: redefinition of f( int() )
void d( int (*)() ) {}
};
[4.5] Parameter declaration that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.
class X
{
public:
void f( int a ) {}
// violation of [4.5]
void f( const int b ) {}
};
[4.5.1] Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations. In particular, for any type T, "pointer to T," "pointer to const T," and "pointer to volatile T" are considered distinct parameter types, as are "reference to T," "reference to const T," and "reference to volatile T."
class X
{
public:
void f( int a ) {}
void f( const int* b ) {} // valid
void f( float c ) {}
void f( const float& d ) {} // valid
};
[4.6] Two parameter declarations that differ only in their default arguments are equivalent hence cannot be overloaded.
class X
{
public:
void f( int a, int b = 100 ) {}
// violation of [4.6]
void f( int c, int d = 222 ) {}
};
0 comments:
Subscribe to:
Post Comments (Atom)