#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)>());
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHNpemVfdCBzej4Kc3RydWN0IFMge307Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kdm9pZCBvdmVybG9hZF9ub3R5cGVuYW1lIChUIHgsIFM8c2l6ZW9mKFQ6OmEpPiB5KSB7IHN0ZDo6Y291dCA8PCAib25lXG4iOyB9CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIG92ZXJsb2FkX25vdHlwZW5hbWUgKFQgeCwgLi4uKSB7IHN0ZDo6Y291dCA8PCAidHdvXG4iOyB9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kdm9pZCBvdmVybG9hZF90eXBlbmFtZSAoVCB4LCBTPHNpemVvZih0eXBlbmFtZSBUOjphKT4geSkgeyBzdGQ6OmNvdXQgPDwgIm9uZVxuIjsgfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kdm9pZCBvdmVybG9hZF90eXBlbmFtZSAoVCB4LCAuLi4pIHsgc3RkOjpjb3V0IDw8ICJ0d29cbiI7IH0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIG92ZXJsb2FkX25vdGVtcGxhdGUgKFQgeCwgUzxzaXplb2YoVDo6YTwzPig1KSk+IHkpIHsgc3RkOjpjb3V0IDw8ICJvbmVcbiI7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnZvaWQgb3ZlcmxvYWRfbm90ZW1wbGF0ZSAoVCB4LCAuLi4pIHsgc3RkOjpjb3V0IDw8ICJ0d29cbiI7IH0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIG92ZXJsb2FkX3RlbXBsYXRlIChUIHgsIFM8c2l6ZW9mKFQ6OnRlbXBsYXRlIGE8Mz4oNSkpPiB5KSB7IHN0ZDo6Y291dCA8PCAib25lXG4iOyB9CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIG92ZXJsb2FkX3RlbXBsYXRlIChUIHgsIC4uLikgeyBzdGQ6OmNvdXQgPDwgInR3b1xuIjsgfQoKc3RydWN0IEsKewogIHR5cGVkZWYgaW50IGE7Cn07CgpzdHJ1Y3QgVwp7CiAgc3RhdGljIGNvbnN0IGludCBhID0gMzsKfTsKCnN0cnVjdCBaCnsKICB0ZW1wbGF0ZTxpbnQ+IHN0YXRpYyBib29sIGEoaW50KSB7IHJldHVybiB0cnVlOyB9Cn07CgppbnQgbWFpbiAoKQp7CiAgb3ZlcmxvYWRfbm90eXBlbmFtZShLKCksIFM8c2l6ZW9mKGludCk+KCkpOwogIG92ZXJsb2FkX3R5cGVuYW1lKEsoKSwgUzxzaXplb2YoaW50KT4oKSk7CgogIG92ZXJsb2FkX25vdHlwZW5hbWUoVygpLCBTPHNpemVvZihpbnQpPigpKTsKICBvdmVybG9hZF90eXBlbmFtZShXKCksIFM8c2l6ZW9mKGludCk+KCkpOwoKICBvdmVybG9hZF9ub3RlbXBsYXRlKFcoKSwgUzxzaXplb2YoYm9vbCk+KCkpOwogIC8vIG92ZXJsb2FkX3RlbXBsYXRlKFcoKSwgUzxzaXplb2YoYm9vbCk+KCkpOwoKICBvdmVybG9hZF9ub3RlbXBsYXRlKFooKSwgUzxzaXplb2YoYm9vbCk+KCkpOwogIG92ZXJsb2FkX3RlbXBsYXRlKFooKSwgUzxzaXplb2YoYm9vbCk+KCkpOwp9