#include <iostream>
using namespace std;

#if 0
template <class F1, class F2>
struct overload : F1, F2 {
  overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }

  using F1::operator();
  using F2::operator();
};

template <class F1, class F2>
auto make_overload(F1 f1, F2 f2) {
  return overload<F1, F2>(f1, f2);
}
#else
template <class... Fs>
struct overload;

template <class F0, class... Frest>
struct overload<F0, Frest...> : F0, overload<Frest...> {
  overload(F0 f0, Frest... rest) : F0(f0), overload<Frest...>(rest...) {}

  using F0::operator();
  using overload<Frest...>::operator();
};

template <class F0>
struct overload<F0> {
  overload(F0 f0) : F0(f0) {}
  using F0::operator();
};

template <class... Fs>
auto make_overload(Fs... fs) {
  return overload<Fs...>(fs...);
}
#endif

#if 0
#define CAP
#define PRINTY()
#else
#define CAP =
#define PRINTY() cout << "int y==" << y << endl
#endif

int main(int argc, char *argv[]) {
	int y = 123;

	auto f = make_overload(
		[CAP] (int x) { cout << "int x==" << x << endl; PRINTY(); },
		[CAP] (char *cp) { cout << "char *cp==" << cp << endl; PRINTY(); });
	f(argc);
	f(argv[0]);
}