Trait模板类,用于检查类是否有具有特定名称的成员



我编写了下面的代码来检查一个类是否先调用了一个成员:

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);
};

通过定义valid_typenot_valid_typestruct {char数组[2];}我们可以让最后一行sizeof(__test<T>(0)) == sizeof(valid_type);根据实例化函数__test返回true或false,从而确定类是否具有名为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);
}

但是我得到了输出:

0

0

在c++ 98中,使用SFINAE检查表达式是否有效可以这样做:

template <class T>
struct has_member_named_first
{
private:
typedef char valid_type;
typedef char(&not_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);
};

要检查数据成员,可以将YOUR_EXPRESSION_HERE设置为static_cast<U*>(0)->first或简单地设置为U::first

检查成员函数或数据成员,使用&U::first

最新更新