Skip to content

Instantly share code, notes, and snippets.

@chen3feng
Created March 8, 2024 07:49
Show Gist options
  • Save chen3feng/9752e0d02670c5acfa38b8d87217fc64 to your computer and use it in GitHub Desktop.
Save chen3feng/9752e0d02670c5acfa38b8d87217fc64 to your computer and use it in GitHub Desktop.
Test a c++ class has member function
#include <iostream>
#include <string>
#include <type_traits>
// Primary template with a static assertion
// for a meaningful error message
// if it ever gets instantiated.
// We could leave it undefined if we didn't care.
#define DEFINE_HAS_METHOD(TraitsName, MethodName) \
template<typename, typename T> \
struct TraitsName { \
static_assert( \
std::integral_constant<T, false>::value, \
"Second template parameter needs to be of function type."); \
}; \
\
template<typename C, typename Ret, typename... Args> \
struct TraitsName<C, Ret(Args...)> { \
private: \
template<typename T> \
static constexpr auto check(T*) \
-> typename \
std::is_same< \
decltype( std::declval<T>().MethodName( std::declval<Args>()... ) ), \
Ret \
>::type; \
\
template<typename> \
static constexpr std::false_type check(...); \
\
typedef decltype(check<C>(0)) type; \
\
public: \
static constexpr bool value = type::value; \
}
DEFINE_HAS_METHOD(has_serialize, serialize);
DEFINE_HAS_METHOD(has_clear, clear);
struct X {
int serialize(const std::string&) { return 42; }
void clear() { }
};
struct Y : X {};
int main() {
std::cout << has_serialize<Y, int(const std::string&)>::value; // will print 1
std::cout << has_clear<Y, void()>::value; // will print 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment