#include <iostream>
#include <functional>
#include <memory>
template <typename T, typename V>
int mao(T&& t, V&& v, decltype( (t.*v)(0), (int)0 ) = 0)
{//オブジェクトとメンバーポインタの組み合わせ
return 0;
}
template <typename T, typename V>
int mao(T&& t, V&& v, decltype( (*t.*v)(0), (char)0 ) = 0)
{//ポインタ(生ポ/スマポ)とメンバーポインタの組み合わせ
return 1;
}
template <typename T, typename V>
int mao(T&& t, V&& v, ...)
{//それ以外
return -1;
}
struct test {
int a;
test(int b) : a(b) { }
int get(int b) const { return a+b; }
};
int main()
{
test a(7);
std::unique_ptr<test> p(new test(8));
std::cout << mao(a, &test::get) << std::endl;
std::cout << mao(&a, &test::get) << std::endl;
std::cout << mao(p, &test::get) << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPG1lbW9yeT4KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBWPgppbnQgbWFvKFQmJiB0LCBWJiYgdiwgZGVjbHR5cGUoICh0Lip2KSgwKSwgKGludCkwICkgPSAwKQp7Ly/jgqrjg5bjgrjjgqfjgq/jg4jjgajjg6Hjg7Pjg5Djg7zjg53jgqTjg7Pjgr/jga7ntYTjgb/lkIjjgo/jgZsKCXJldHVybiAwOwp9CnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBWPgppbnQgbWFvKFQmJiB0LCBWJiYgdiwgZGVjbHR5cGUoICgqdC4qdikoMCksIChjaGFyKTAgKSA9IDApCnsvL+ODneOCpOODs+OCv++8iOeUn+ODne+8j+OCueODnuODne+8ieOBqOODoeODs+ODkOODvOODneOCpOODs+OCv+OBrue1hOOBv+WQiOOCj+OBmwoJcmV0dXJuIDE7Cn0KdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFY+CmludCBtYW8oVCYmIHQsIFYmJiB2LCAuLi4pCnsvL+OBneOCjOS7peWklgoJcmV0dXJuIC0xOwp9CgpzdHJ1Y3QgdGVzdAl7CglpbnQgYTsKCXRlc3QoaW50IGIpIDogYShiKSB7IH0KCWludCBnZXQoaW50IGIpIGNvbnN0IHsgcmV0dXJuIGErYjsgfQp9OwoKaW50ICBtYWluKCkKewoJdGVzdCBhKDcpOwoJc3RkOjp1bmlxdWVfcHRyPHRlc3Q+IHAobmV3IHRlc3QoOCkpOwoJc3RkOjpjb3V0IDw8IG1hbyhhLCAmdGVzdDo6Z2V0KSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgbWFvKCZhLCAmdGVzdDo6Z2V0KSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgbWFvKHAsICZ0ZXN0OjpnZXQpIDw8IHN0ZDo6ZW5kbDsKCXJldHVybiAwOwp9
prog.cpp: In function ‘int main()’:
prog.cpp:31:32: error: call of overloaded ‘mao(test&, int (test::*)(int)const)’ is ambiguous
std::cout << mao(a, &test::get) << std::endl;
^
prog.cpp:31:32: note: candidates are:
prog.cpp:6:5: note: int mao(T&&, V&&, decltype ((*mao::t.**mao::v(0), (int)(0)))) [with T = test&; V = int (test::*)(int)const; decltype ((*mao::t.**mao::v(0), (int)(0))) = int]
int mao(T&& t, V&& v, decltype( (t.*v)(0), (int)0 ) = 0)
^
prog.cpp:16:5: note: int mao(T&&, V&&, ...) [with T = test&; V = int (test::*)(int)const]
int mao(T&& t, V&& v, ...)
^
prog.cpp:32:33: error: call of overloaded ‘mao(test*, int (test::*)(int)const)’ is ambiguous
std::cout << mao(&a, &test::get) << std::endl;
^
prog.cpp:32:33: note: candidates are:
prog.cpp:11:5: note: int mao(T&&, V&&, decltype ((**mao::t.**mao::v(0), (char)(0)))) [with T = test*; V = int (test::*)(int)const; decltype ((**mao::t.**mao::v(0), (char)(0))) = char]
int mao(T&& t, V&& v, decltype( (*t.*v)(0), (char)0 ) = 0)
^
prog.cpp:16:5: note: int mao(T&&, V&&, ...) [with T = test*; V = int (test::*)(int)const]
int mao(T&& t, V&& v, ...)
^
prog.cpp:33:32: error: call of overloaded ‘mao(std::unique_ptr<test>&, int (test::*)(int)const)’ is ambiguous
std::cout << mao(p, &test::get) << std::endl;
^
prog.cpp:33:32: note: candidates are:
prog.cpp:11:5: note: int mao(T&&, V&&, decltype ((**mao::t.**mao::v(0), (char)(0)))) [with T = std::unique_ptr<test>&; V = int (test::*)(int)const; decltype ((**mao::t.**mao::v(0), (char)(0))) = char]
int mao(T&& t, V&& v, decltype( (*t.*v)(0), (char)0 ) = 0)
^
prog.cpp:16:5: note: int mao(T&&, V&&, ...) [with T = std::unique_ptr<test>&; V = int (test::*)(int)const]
int mao(T&& t, V&& v, ...)
^