#include <string>
#include <cstdint>
#include <iostream>
using std::cout;

/** Example showing why you need to be careful with
 * implicit type conversions.
 * A string literal is a char*, which can be
 * implicitly converted to a std::string.
 * But it can also be implicitly converted to bool,
 * and according to the standard, the conversion to
 * bool is "better" than to a user-defined type like
 * std::string, so for a function that has overloads
 * for both std::string and bool, calling it with
 * a string literal will call the bool overload.
 */

void foo(const std::string& s)
{
    cout << "foo(string): " << s << '\n';
}

void foo(bool b)
{
    cout << "foo(bool): " << b << '\n';
}

void foo(long i)
{
    cout << "foo(long): " << i << '\n';
}

void example1()
{
    cout << "example1:\n";
    foo("Hello!");
}

/** Example showing explicit casts,
 * By casting 
 *
 */
void example2()
{
    cout << "example2:\n";
    foo(static_cast<const std::string&>("Hello"));
    foo(static_cast<bool>("Hello"));
#ifdef ERROR
    // A char* is not an integer, so static_cast cannot be used
    foo(static_cast<intptr_t>("Hello"));
#else
    foo(reinterpret_cast<intptr_t>("Hello"));
#endif
}

int main()
{
    example1();
    example2();
}


