#include <iostream>

template <size_t sz>
struct S {};

template <typename T>
void overload_notypename (T x, S<sizeof(T::a)> y) { std::cout << "one\n"; }
template <typename T>
void overload_notypename (T x, ...) { std::cout << "two\n"; }

template <typename T>
void overload_typename (T x, S<sizeof(typename T::a)> y) { std::cout << "one\n"; }
template <typename T>
void overload_typename (T x, ...) { std::cout << "two\n"; }

template <typename T>
void overload_notemplate (T x, S<sizeof(T::a<3>(5))> y) { std::cout << "one\n"; }
template <typename T>
void overload_notemplate (T x, ...) { std::cout << "two\n"; }

template <typename T>
void overload_template (T x, S<sizeof(T::template a<3>(5))> y) { std::cout << "one\n"; }
template <typename T>
void overload_template (T x, ...) { std::cout << "two\n"; }

struct K
{
  typedef int a;
};

struct W
{
  static const int a = 3;
};

struct Z
{
  template<int> static bool a(int) { return true; }
};

int main ()
{
  overload_notypename(K(), S<sizeof(int)>());
  overload_typename(K(), S<sizeof(int)>());

  overload_notypename(W(), S<sizeof(int)>());
  overload_typename(W(), S<sizeof(int)>());

  overload_notemplate(W(), S<sizeof(bool)>());
  // overload_template(W(), S<sizeof(bool)>());

  overload_notemplate(Z(), S<sizeof(bool)>());
  overload_template(Z(), S<sizeof(bool)>());
}