用于检查成员是否存在的模板专门化

时间:2015-09-17 22:50:49

标签: c++ templates c++11

这是我的问题SFINAE with variadic templates的后续跟进。我试图构建一个名为has_member的可变参数模板,用于检查类是否有成员(称为member)。

我试着看看我是否可以在问题的答案中使用size_t代替void,而不是使用可变参数模板,如下所示:

#include <iostream>
#include <vector>
using namespace std;

class ClassWithMember
{
    public:
    int member;
};
class ClassWithoutMember
{
};

template <typename T,typename=size_t>
class has_member: public std::false_type
{
};
template <typename T>
class has_member<T,decltype(sizeof(typename T::member))>: public std::true_type
{
};

template <typename T1,
          std::enable_if_t<has_member<T1>::value>* = nullptr>
void my_function(const T1& obj) { cout<<"Function for classes with member"<<endl; }

template <typename T1,
          std::enable_if_t<!has_member<T1>::value>* = nullptr>
void my_function(const T1& obj) { cout<<"Function for classes without member"<<endl; }


int main()
{
    ClassWithMember objWithMember;
    ClassWithoutMember objWithoutMember;
    my_function (objWithMember);
    my_function (objWithoutMember);
}

我没有错误,但从未使用过专业化。只调用没有该成员的类的函数。有人可以解释一下原因吗?

1 个答案:

答案 0 :(得分:1)

T::member之前的类型名称是不必要的。

#include <iostream>
#include <vector>
using namespace std;

class ClassWithMember
{
    public:
    int member;
};
class ClassWithoutMember
{
};

template <typename T,typename=size_t>
class has_member: public std::false_type
{
};

template <typename T>
class has_member<T,decltype(sizeof(T::member))>: public std::true_type
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
{
};

template <typename T1,
          std::enable_if_t<has_member<T1>::value>* = nullptr>
void my_function(const T1& obj) { cout<<"Function for classes with member"<<endl; }

template <typename T1,
          std::enable_if_t<!has_member<T1>::value>* = nullptr>
void my_function(const T1& obj) { cout<<"Function for classes without member"<<endl; }


int main()
{
    ClassWithMember objWithMember;
    ClassWithoutMember objWithoutMember;
    my_function (objWithMember);
    my_function (objWithoutMember);
}

<强> Demo

[OT]只是进一步元编程的提示:您还可以使用真实类型而不是模板进行测试。