void print( const string &str );
void print( const string & ); // redeclaration (legal)
void f( int );
void f( const int ); // redeclaration (legal)
int max( int *ia, int sz );
int max( int *, int sz = 10 ); // legal
typedef double DOLLAR;
extern DOLLAR calc( DOLLAR );
extern int calc( double ); // error
unsigned int max( int i1, int i2 );
int max( int , int ); // error: only return type is different
void print( const string & );
void print( vector<int> & ); // overloaded
void f( int* );
void f( const int* ); // overloaded
void f( int& );
void f( const int& ); // overloaded
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.
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;
}
#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*)
}
#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)
}
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
}
namespace libs_R_us {
int max( int, int );
double max( double, double );
}
char max( char, char );
using libs_R_us::max;
void func()
{
// Candadiate at here:
// libs_R_us::max(int,int)
// libs_R_us::max(double,double)
// ::max(char,char)
}
namespace libs_R_us {
int max( int, int );
double max( double, double );
}
char max( char, char );
void func()
{
using libs_R_us::max;
// Candadiate at here:
// libs_R_us::max(int,int)
// libs_R_us::max(double,double)
// ::max( char, char ) is hidden
}
libs_R_us has been lifted up the lowest common ancestor of the current namespace and the target namespace. I.e., global namespace. See here
namespace libs_R_us {
int max( int, int );
double max( double, double );
}
char max( char, char );
using namespace libs_R_us;
void func()
{
// Candadiate at here:
// libs_R_us::max(int,int)
// libs_R_us::max(double,double)
// ::max(char,char)
}
namespace libs_R_us {
int max( int, int );
double max( double, double );
}
char max( char, char );
void func()
{
using namespace libs_R_us;
// Candadiate at here:
// libs_R_us::max(int,int)
// libs_R_us::max(double,double)
// ::max( char, char )
}
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
}
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)
}