template instantiation check for member existing in class

前端 未结 1 845
抹茶落季
抹茶落季 2021-01-06 19:51

I have a group of classes that have one or more members of the type memberA, memberB, memberC. Not all classes have all the members. I want to create a template that will se

相关标签:
1条回答
  • 2021-01-06 20:11

    Here's a possible set_memberA_if_exists implementation:

    namespace details {
        template<class T>
        auto set_memberA_if_exists_impl(T & myClass, typeA memA, int) 
             -> decltype(myClass.memberA = memA, void()) {
            myClass.memberA = memA;
        }
    
        template<class T>
        void set_memberA_if_exists_impl(T & myClass, typeA memA, long) {}
    }
    
    template<class T>
    void set_memberA_if_exists(T & myClass, typeA memA) {
         details::set_memberA_if_exists_impl(myClass, memA, 0);
    }
    

    Explanation:

    SFINAE applies only to the signature, not the body, of the function template, so the trick is to encode the check inside the function template signature. This is easy using a C++11 trailing return type - -> decltype(myClass.memberA = memA, void()). If the expression myClass.memberA = memA would not compile, then it causes a substitution failure and removes the function template from the overload set. So that a call to set_memberA_if_exists_impl will still compile in that case, we also provide another do-nothing overload.

    We also need a way to distinguish between those two overloads when they are both viable. This is done by introducing a third parameter. The do-something overload's third parameter's type is int, while the do-nothing overload's is long. By providing 0 (an int) as the third argument when we call it, we make sure that the do-something overload is preferred when it is viable.

    0 讨论(0)
提交回复
热议问题