#include <string>
#include <typeinfo>
#include <iostream>

template <typename T>
void
type_of(const T& x)
{
  std::cout << typeid(x).name() << std::endl;
}

template <typename T>
void
my_type_of(const T& x)
{
  std::cout << "Type of " << x << " unknown" << std::endl;
}

template <>
void
my_type_of(const unsigned& x)
{
  std::cout << "unsigned" << std::endl;
}

template <>
void
my_type_of(const int& x)
{
  std::cout << "int" << std::endl;
}


int
main()
{
  std::string f("foo");
  type_of(std::string::npos);
  type_of(f.find("foo"));
  
  int a = -1;
  unsigned b = -1;

  my_type_of(std::string::npos);
  my_type_of(f.find("foo"));
  my_type_of(a);

  if (a == b) 
    std::cout << "a (" << a << ") is equal to b ("  << b << ")" << std::endl;
  else
    std::cout << "a (" << a << ") is not equal to b ("  << b << ")" << std::endl;

  return 0;
}



