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

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

template <typename V, typename T>
std::int16_t test(V&& v, T&& t, decltype((t->*v)((int)0))* = 0) {
    return 0;
}

template <typename V, typename T>
std::int32_t test(V&& v, T&& t, decltype((t.operator->()->*v)((int)0))* = 0) {
    return 0;
}

std::int64_t test(...) {
    return 0;
}

struct ichikawa {
    int fun(int a) const {
        return 2 * a;
    }
};

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

    std::cout << (*sp.*pF)(7) << std::endl;	//14

    auto result1 = test(pF, ic);
    auto result2 = test(pF, &ic);
    auto result3 = test(pF, sp);
    auto result4 = test(2014, 01/02);

    std::cout << sizeof(result1) << std::endl;
    std::cout << sizeof(result2) << std::endl;
    std::cout << sizeof(result3) << std::endl;
    std::cout << sizeof(result4) << std::endl;

    return 0;
}
