Question

I have lots of nodes from CCNode subclasses and some of them have the function ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent). Now my question is if it's possible to check if they own this particular function with SFINAE. I tried to make it work with the help of that thread: Is it possible to write a template to check for a function's existence? but I can't.

Here's what I have:

template <typename T>
class hasMethodCCTouchBegan
{
    typedef char yes;
    typedef long no;

    template <typename C> static yes test( decltype(&C::ccTouchBegan) ) ;
    template <typename C> static no test(...);

public:
    enum { value = sizeof(test<T>(0)) == sizeof(yes) };
};

Honestly I have no clue what to do.

Was it helpful?

Solution

I personally use (in C++11):

#include <cstdint>

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)               \
    template <typename U>                                                   \
    class traitsName                                                        \
    {                                                                       \
    private:                                                                \
        template<typename T, T> struct helper;                              \
        template<typename T>                                                \
        static std::uint8_t check(helper<signature, &funcName>*);           \
        template<typename T> static std::uint16_t check(...);               \
    public:                                                                 \
        static                                                              \
        constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
    }

// Create your traits:
DEFINE_HAS_SIGNATURE(has_ccTouchBegan, T::ccTouchBegan, bool (T::*)(CCTouch *, CCEvent *));

OTHER TIPS

template<class C>
decltype(&C::ccTouchBegan, std::true_type())
methodHelper(int);

template<class C>
std::false_type
methodHelper(...);

template<class C>
struct hasMethodCCTouchBegan : decltype(methodHelper<C>(0))
{
};

This won't work if ccTouchBegan is overloaded. If you want to test whether ccTouchBegan can be called with certain arguments then you can change &C::ccTouchBegan to std::declval<C>().ccTouchBegan(std::declval<CCTouch*>(), std::declval<CCEvent*>()).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top