【问题标题】:Template specialization to check whether a member is present用于检查成员是否存在的模板特化
【发布时间】:2015-09-17 22:50:48
【问题描述】:

这是对我的问题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);
}

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

【问题讨论】:

    标签: c++ templates c++11


    【解决方案1】:

    T::member 前面的 typename 是不需要的。

    #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] 只是进一步元编程的提示:您还可以使用真实类型而不是模板进行测试。

    【讨论】:

    • 成功了!能否请您添加一个简短的解释?
    • 看起来真实类型没有问题。它显然是在 c++0x 中引入的。 stackoverflow.com/questions/5976879/… 那么为什么模板有问题呢?我把丹尼斯在他回答最后提到的内容整理出来,完全没有错误。
    • 已更正,typename 关键字不是必需的。
    • 我认为这不是依赖类型:error: typename specifier refers to non-type member 'member' in 'ClassWithMember'
    • 嗯..是的。我没有看到您提到的错误,但 member 并不是真正的类型。这就解释了..
    猜你喜欢
    • 2021-09-04
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 2015-04-23
    • 2014-02-21
    相关资源
    最近更新 更多