Declarations

  1. If both the return type and the parameter list of the two function declarations match exactly, the second declaration is treated as a redeclaration of the first.
     void print( const string &str );
     void print( const string & );    // redeclaration (legal)
    
  2. Top-level cv-qualifiers are ignored when comparing parameter types.
     void f( int );
     void f( const int ); // redeclaration (legal)
    
  3. If the parameter lists of the two functions differ only in their default arguments, the second declaration is treated as a redeclaration of the first.
     int max( int *ia, int sz );
     int max( int *, int sz = 10 ); // legal
    

    Erroneous redeclaration

  4. If the parameter lists of the two functions differ only in that one uses a typedef and the other uses the type to which the typedef corresponds, the second declaration is treated as an erroneous redeclaration.
     typedef double DOLLAR;
     extern DOLLAR calc( DOLLAR );
     extern int calc( double );    // error
    
  5. If the parameter lists of the two functions match exactly but the return types differ, the second declaration is treated as an erroneous redeclaration of the first and is flagged at compile-time as an error.
     unsigned int max( int i1, int i2 );
     int max( int , int );                 // error: only return type is different
    

    Overloaded function declarations

  6. If the parameter lists of the two functions differ in either the number or type of their parameters, the two functions are considered to be overloaded.
     void print( const string & );
     void print( vector<int> & ); // overloaded
    
  7. Low-level cv-qualifiers are considered part of the parameter type.
     void f( int* );
     void f( const int* ); // overloaded
    
     void f( int& );
     void f( const int& ); // overloaded
    

    Overloading and scope

    The candidate functions are the union of the overloaded functions that 1) has the same name as the function called and 2) visible at the point of the call — including the functions introduced by using declarations and using directives — and 3) the member functions declared in the namespaces associated with the types of the arguments.

  8. If the type of a function argument is declared within a namespace, the namespace member functions that have the same name as the function called are added to the set of candidate functions. I.e., argument-dependent lookup (ADL).
     namespace NS {
     class C { /* ... */ };
         void takeC( C& );
     }
    	
     // the type of cobj is class C declared in namespace NS
     NS::C cobj;
    	
     int main() {
    	
         // no takeC() visible at here
    	    
         takeC( cobj ); // ok: calls NS::takeC( C& )
                        // because the argument is of type NS::C
                        // the function takeC() declared in
                        // namespace NS is considered
     return 0;
     }
    
  9. A locally declared function hides rather than overloads all functions declared at global scope.
     #include<iostream>
     #include<string>
    	
     void print( const std::string & );
     void print( double );
    	
     void foo()
     {
        extern void print( int );
        // Candidate functions at here: print(int)
        // local declaration hides both instances of global print()
        print(1); // Call print(int)
        print("abc"); // Error: print(const std::string&) is hidden in this scope
        print(1.4); // Call print(int)
     }
    	
     void print(const std::string&) { std::cout << "string" << std::endl; };
     void print(double) { std::cout << "double" << std::endl; };
     void print(int) { std::cout << "int" << std::endl; };
    	
     int main(){
        foo();
        return 0;
     }
    
     char* format( int );
     void g() {
         char* format( double );
         char* format( char* );
            
         // Candidate functions at here
         // format(double)
         // format(char*)
     }
    
  10. A set of overloaded functions can also be declared within a class. TBD
  11. A set of overloaded functions can also be declared within a namespace.
     #include <string>
    	
     namespace IBM {
         extern void print( const string );
         extern void print( double );
         // Candidates:
         // print(double)
         // print(const string)
     }
     namespace Disney {
         extern void print( int );
         // Candidates:
         // print(int)
     }
    
  12. using declaration vs. using directive
     namespace libs_R_us {
        int max( int, int );
        double max( double, double );
     }
     char max( char, char );
     void func()
     {
        // Only the global function max( char, char ) is visible at here
     }
    
  13. If the using declaration introduces a function in a scope that already has a function of the same name with the same parameter list, then the using declaration is in error.
     namespace libs_R_us {
         void print( int );
         void print( double );
     }
     void print( int );
     using libs_R_us::print; // error: redeclaration of print(int)
     void fooBar( int ival )
     {
         // Cadidates: nothing
     }
    
  14. Multiple using directives are present. The member functions from different namespaces that have the same name are added to the same overload set.
     namespace IBM {
         int print(int);
     }
     namespace Disney {
         double print(double);
     }
     // using directives:
     // form an overload set of functions from different namespaces
     using namespace IBM;
     using namespace Disney;
     long double print(long double);
    	
     int main() {
         // Candidate functions:
         // IBM::print(int)
         // Disney::print(double)
         // long double print(long double)
     }