#include <iostream>
#include <vector>

template<class T, class F1>
class is_functor_enable {
	struct detector {};
	template<class Y>
	static auto search(Y &&)-> std::conditional_t<false, decltype(std::declval<F1>()(std::declval<Y>())), void>;
	static auto search(...) -> detector;
public:
	static constexpr bool value = !std::is_same<decltype(search(std::declval<T>())), detector>::value;
};

#define GC_IS_HAS_METHOD(_arg_type, _arg_meth_name, ...) []() -> auto {\
		auto l = [](auto && lambda_arg) -> std::conditional<false, decltype(std::declval< decltype(lambda_arg) >(). _arg_meth_name ( __VA_ARGS__ )), void> {};\
		return is_functor_enable<_arg_type, decltype(l)>::value;\
	}()

int main() {
	// your code goes here
	std::cout 
	<< ' ' << GC_IS_HAS_METHOD(std::vector<int>, size, ) //is vector<int> has method size, which takes nothing
	<< ' ' << GC_IS_HAS_METHOD(std::vector<int>, push_back, std::declval<int &>()) //is vector<int> has method push_back, which takes int &
	<< ' ' << GC_IS_HAS_METHOD(std::vector<int>, insert, std::declval<std::vector<int>::iterator>(), std::declval<int &>()) //is vector<int> has method insert, which takes iterator and value
	<< ' ' << GC_IS_HAS_METHOD(std::vector<int>, foo, 3,4,5,6,7) //is vector<int> has method foo, which takes 5 ints
	;
	return 0;
}