Howto check a type for the existence of parameterless operator()

前端 未结 2 1482
北荒
北荒 2021-02-06 09:33

I\'m trying to check whether a functor is compatible with a given set of parametertypes and a given return type (that is, the given parametertypes can be implicitely converted t

相关标签:
2条回答
  • 2021-02-06 10:21

    When I want to test if a given expression is valid for a type, I use a structure similar to this one:

    template <typename T>
    struct is_callable_without_parameters {
    private:
        template <typename T1>
        static decltype(std::declval<T1>()(), void(), 0) test(int);
        template <typename>
        static void test(...);
    public:
        enum { value = !std::is_void<decltype(test<T>(0))>::value };
    };
    
    0 讨论(0)
  • 2021-02-06 10:31

    Have you tried something like:

    template<size_t>
    class Discrim
    {
    };
    
    template<typename T>
    std::true_type hasFunctionCallOper( T*, Discrim<sizeof(T()())>* );
    
    template<typename T>
    std::false_type hasFunctionCallOper( T*, ... );
    

    After, you discriminate on the return type of hasFunctionCallOper((T*)0, 0).

    EDITED (thanks to the suggestion of R. Martinho Fernandes):

    Here's the code that works:

    template<size_t n>
    class CallOpDiscrim {};
    
    template<typename T>
    TrueType hasCallOp( T*, CallOpDiscrim< sizeof( (*((T const*)0))(), 1 ) > const* );
    template<typename T>
    FalseType hasCallOp( T* ... );
    
    template<typename T, bool hasCallOp>
    class TestImpl;
    
    template<typename T>
    class TestImpl<T, false>
    {
    public:
        void doTellIt() { std::cout << typeid(T).name() << " does not have operator()" << std::endl; }
    };
    
    template<typename T>
    class TestImpl<T, true>
    {
    public:
        void doTellIt() { std::cout << typeid(T).name() << " has operator()" << std::endl; }
    };
    
    template<typename T>
    class Test : private TestImpl<T, sizeof(hasCallOp<T>(0, 0)) == sizeof(TrueType)>
    {
    public:
        void tellIt() { this->doTellIt(); }
    };
    
    0 讨论(0)
提交回复
热议问题