#include <type_traits> // To use 'std::integral_constant'.
#include <iostream> // To use 'std::cout'.
#include <iomanip> // To use 'std::boolalpha'.
#include <map>
#include <vector>
#define GENERATE_HAS_MEMBER(member) \
\
template < class T > \
class HasMember_##member \
{ \
private: \
using Yes = char[2]; \
using No = char[1]; \
\
struct Fallback { int member; }; \
struct Derived : T, Fallback { }; \
\
template < class U > \
static No& test ( decltype(U::member)* ); \
template < typename U > \
static Yes& test ( U* ); \
\
public: \
static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
}; \
\
template < class T > \
struct has_member_##member \
: public std::integral_constant<bool, HasMember_##member<T>::RESULT> \
{ \
};
GENERATE_HAS_MEMBER(find) // Creates 'has_member_func'.
struct B
{
double find ( const char* );
};
int main ( )
{
std::cout << std::boolalpha
<< "\n" "'find' in 'B' : "
<< has_member_find<B>() // <type_traits>-like interface.
<< "\n" "'find' in 'std::map' : "
<< has_member_find<std::map<int,int> >() // Implicitly convertible to 'bool'.
<< "\n" "'find' in 'std::vector' : "
<< has_member_find<std::vector<int> >() // Implicitly convertible to 'bool'.
<< "\n";
}