Check if class has function with signature

后端 未结 3 540
遇见更好的自我
遇见更好的自我 2020-12-21 17:31

There are other answers on this site using SFINAE but with non C++11 code, and there are others using C++11 code like decltypes to make this process easier. However, I am no

相关标签:
3条回答
  • 2020-12-21 18:05

    There is help with macros:

    #define DEFINE_METHOD_CHECKER(RETURN_TYPE, METHOD_NAME, PARAMETERS)     \
    template<typename T>                                                    \
    struct Is ## METHOD_NAME ## MemberFunctionExists                        \
    {                                                                       \
    private:                                                                \
        typedef char True;                                                  \
        typedef char (&False)[2];                                           \
        template<typename U, RETURN_TYPE (U::*)PARAMETERS = &U::METHOD_NAME>\
        struct Checker                                                      \
        {                                                                   \
            typedef True Type;                                              \
        };                                                                  \
        template<typename U>                                                \
        static typename Checker<U>::Type Tester(const U*);                  \
        static False Tester(...);                                           \
    public:                                                                 \
        enum { value = (sizeof(Tester(static_cast<const T*>(0))) == sizeof(True)) }; \
    }
    
    // IsMethodMemberFunctionExists<T>::value
    DEFINE_METHOD_CHECKER(int, Method, (bool));
    // IsTestMemberFunctionExists<T>::value
    DEFINE_METHOD_CHECKER(int*, Test, (int&, char));
    
    #include <iostream>
    
    class Exists
    {
    public:
        int Method(bool);
        int* Test(int&, char);
    
    };
    
    class NotExists
    {
    };
    
    int main()
    {
        std::cout << IsMethodMemberFunctionExists<Exists>::value << std::endl;
        std::cout << IsTestMemberFunctionExists<Exists>::value << std::endl;
    
        std::cout << IsMethodMemberFunctionExists<NotExists>::value << std::endl;
        std::cout << IsTestMemberFunctionExists<NotExists>::value << std::endl;
    }
    

    So, in your case you need to define a few checkers - one checker for one type of Event:

    // void recieve(const Event1&)
    DEFINE_METHOD_CHECKER(void, recieve, (const Event1&));
    
    // void recieve(const Event2&)
    DEFINE_METHOD_CHECKER(void, recieve, (const Event2&));
    
    0 讨论(0)
  • 2020-12-21 18:13

    The best way I know of is checking if you can actually call the function and if it returns the type you expect. Here's an example of how to detect if a class C has a receive method which takes const Event& as a parameter and "returns" void. The detection does not care whether the method is implemented in the class C directly or in some base class that C derives from, neither does it care whether there are further defaulted parameters. Adapt as needed.

    template< typename C, typename Event, typename = void >
    struct has_receive
      : std::false_type
    {};
    
    template< typename C, typename Event >
    struct has_receive< C, Event, typename std::enable_if<
        std::is_same<
            decltype( std::declval<C>().receive( std::declval<const Event&>() ) ),
            void
        >::value
    >::type >
      : std::true_type
    {};
    
    0 讨论(0)
  • 2020-12-21 18:16

    You may use the following to match exact signature:

    template <typename U, typename Event>
    class has_receive
    {
    private:
        template<typename T, T> struct helper;
        template<typename T>
        static std::uint8_t check(helper<void (T::*)(const Event &), &T::receive>*);
        template<typename T> static std::uint16_t check(...);
    public:
        static
        constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
    };
    
    0 讨论(0)
提交回复
热议问题