#include <iostream>
#include <utility>
#include <memory>

template <typename V, typename T> 
	char  test(V&& v, T&& t, decltype( (t.*v)((int)0), 0 ) = 0)
	//char  test(V&& v, T&& t, decltype( (t.*v)((int)0) )* = 0)
	{ return 0; }

template <typename V, typename T> 
	short test(V&& v, T&& t, decltype( (*t.*v)((int)0), 0 ) = 0)
	//short test(V&& v, T&& t, decltype( (*t.*v)((int)0) )* = 0)
	{ return 0; }

long  test(...)  { return 0; }

namespace { int static_a; }

struct ichikawa	{
	int fun1(int a) const { return 2*a; }
	int& fun2(int a) const { return static_a; }
	int&& fun3(int a) const { return (int&&)static_a; }
	};

int main() {
	ichikawa ic;
	std::unique_ptr<ichikawa> sp(new ichikawa);
	//int (ichikawa::*pF)(int)const = &ichikawa::fun1;
	//int& (ichikawa::*pF)(int)const = &ichikawa::fun2;
	int&& (ichikawa::*pF)(int)const = &ichikawa::fun3;

	auto result1 = test(pF, ic);
	auto result2 = test(pF, &ic);
	auto result3 = test(pF, sp);
	
	std::cout << sizeof(result1) << std::endl;
	std::cout << sizeof(result2) << std::endl;
	std::cout << sizeof(result3) << std::endl;
	
	std::conditional< 0 < 2, int, char>::type nakamura;
	std::conditional< (0 > 3), int, char>::type kataoka;
	
	return 0;
}