// -----------------------
// FunctionOverloading.c++
// -----------------------

#include <cassert>  // assert
#include <cstring>  // strcmp
#include <iostream> // cout, endl
#include <string>   // string

struct A {};
struct B : A {};

int my_max (int x, int y) {
    if (x < y)
        return y;
    return x;}

int* my_max (int* x, int* y) {
    if (*x < *y)
        return y;
    return x;}

const char* my_max (const char* x, const char* y) {
    if (std::strcmp(x, y) < 0)
        return y;
    return x;}

std::string f (int) {
    return "f(int)";}

//std::string f (const int) { // error: redefinition of "std::string f(int)"
//    return "f(const int)";}

std::string g (int&) {
    return "g(int&)";}

std::string g (const int&) {
    return "g(const int&)";}

//std::string g (int) {       // all calls become ambiguous
//    return "g(int)";}

std::string h (int*) {
    return "h(int*)";}

std::string h (const int*) {
    return "h(const int*)";}

std::string x (int) {
    return "x(int)";}

std::string x (long) {
    return "x(long)";}

std::string y (A) {
    return "y(A)";}

std::string y (B) {
    return "y(B)";}

int main () {
    using namespace std;
    cout << "FunctionOverloading.c++" << endl;

    {
    int i = 2;
    int j = 3;
    assert(my_max(i,     j)     == 3);
    assert(my_max(&i,    &j)    == &j);
    assert(my_max("abc", "def") == string("def"));
    assert(my_max(2.3,   4)     == 4);
    }

    {
          int i = 2;
    const int j = 3;

    assert(f(i)  == "f(int)");
    assert(f(j)  == "f(int)");
    assert(f(4)  == "f(int)");

    assert(g(i)  == "g(int&)");
    assert(g(j)  == "g(const int&)");
    assert(g(4)  == "g(const int&)");

    assert(h(&i) == "h(int*)");
    assert(h(&j) == "h(const int*)");

//  h(0);                                                     // error: call of overloaded "h(int)" is ambiguous
    assert(h(static_cast<int*>(0))       == "h(int*)");
    assert(h(static_cast<const int*>(0)) == "h(const int*)");
    }

    {
    assert(x(2)  == "x(int)");
    assert(x(3L) == "x(long)");
    }

    {
    assert(y(A()) == "y(A)");
    assert(y(B()) == "y(B)");
    }

    cout << "Done." << endl;
    return 0;}


syntax highlighted by Code2HTML, v. 0.9.1