I made this code for checking if a class has a member called first:
template <class T>
struct ClassA{
T first;
};
template <class T>
struct ClassB{
T second;
};
template <class T>
struct has_member_named_first
{
typedef char valid_type;
typedef struct { char array[2]; } not_valid_type;
template <typename U>
static valid_type __test(typename U::first*);
template <typename U>
static not_valid_type __test(...);
static const bool value = sizeof(__test<T>(0)) == sizeof(valid_type);
};
By defining valid_type
as char and not_valid_type
as struct { char array[2]; } we can make the last line sizeof(__test<T>(0)) == sizeof(valid_type);
return true or false based on the instantiated function __test and thus determine if a class has a member named first
.
int main()
{
std::cout << has_type_named_first<ClassA<int> >::value << std::endl;
std::cout << has_type_named_first<ClassB<int> >::value << std::endl;
return (0);
}
but i got in the output:
0
0
In C++98, checks for if an expression is valid using SFINAE can be done like this:
template <class T>
struct has_member_named_first
{
private:
typedef char valid_type;
typedef char(¬_valid_type)[2];
template<std::size_t> struct check_expr;
template <typename U>
static valid_type test(check_expr<sizeof((void) (YOUR_EXPRESSION_HERE), 0)>*);
template <typename U>
static not_valid_type test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(valid_type);
};
To check for a data member, you can have YOUR_EXPRESSION_HERE
be static_cast<U*>(0)->first
or simply U::first
.
To check for a member function or data member, use &U::first
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.