Skip to content

Instantly share code, notes, and snippets.

@gatchamix
Last active October 12, 2018 09:06
Show Gist options
  • Save gatchamix/6e94c68bf3cbd87cd81fcf2160630275 to your computer and use it in GitHub Desktop.
Save gatchamix/6e94c68bf3cbd87cd81fcf2160630275 to your computer and use it in GitHub Desktop.
faux-function to determine whether a class/struct has a function (optionally checking for a specific type signature)
#include <type_traits>
//
template <class...>
struct type_pack
{};
//
namespace detail
{
template <class R, class T>
auto constexpr match(R T::*)
-> std::true_type;
template <class...>
auto constexpr match(...)
-> std::false_type;
}
#define has_member_function(...) \
[] \
{ \
using type = __VA_ARGS__; \
HAS_MEMBER_FUNCTION_IMPL_1
#define HAS_MEMBER_FUNCTION_IMPL_1(...) \
auto constexpr helper = [] \
<class T, class... Sig> \
(type_pack<T, Sig...>) \
-> decltype(detail::match<Sig...>(&T::__VA_ARGS__)) \
{}; \
HAS_MEMBER_FUNCTION_IMPL_2
#define HAS_MEMBER_FUNCTION_IMPL_2(...) \
using input = type_pack<type __VA_OPT__(, __VA_ARGS__)>; \
return std::is_invocable_r_v<std::true_type, decltype(helper), input>; \
}()
//
template <class...>
struct foo
{
template <class T>
auto constexpr func(T) const
-> T;
};
//
auto main()
-> int
{
// check for existance of member functions
//
// usage:
// has_member_function(T[<Ts...>])([template] name[<Us...>])([signature])
// where 'signature' is:
// R([Args...]) [const] [volatile]
static_assert
(
has_member_function
(foo<int, double>) // class/struct
(template func<int>) // member function name
(int(int) const) // [signature]
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment