is_member_function_pointer implementation

前端 未结 2 989
醉话见心
醉话见心 2021-01-15 14:25

I am trying to implement my own is_member_function_pointer and I\'m having trouble with it.

namespace __implementation
{
    // integral_constan         


        
相关标签:
2条回答
  • 2021-01-15 14:54

    Alternatively

    template<typename T> struct remove_c { typedef T type; };
    template<typename T> struct remove_c<T const> { typedef T type; };
    
    template<bool C> 
    struct bool_ { static bool const value = C; };
    
    template<typename T, typename U>
    struct is_same : bool_<false> {};
    
    template<typename T>
    struct is_same<T, T> : bool_<true> { };
    
    template<typename T, typename = bool_<true> >
    struct is_function : bool_<false> {};
    
    struct C { };
    
    template<typename T>
    struct is_function< T, 
       bool_<is_same<typename remove_c<T>::type const C::*, 
                     typename remove_c<T>::type       C::*>::value> > 
      : bool_<true> {};
    
    template<typename T>
    struct is_member_function_pointer_impl : bool_<false> {};
    
    template<typename T, typename C>
    struct is_member_function_pointer_impl<T C::* const volatile>
      : is_function<T> {};
    
    template<typename T>
    struct is_member_function_pointer 
      : is_member_function_pointer_impl<T const volatile> {};
    
    0 讨论(0)
  • 2021-01-15 15:02

    A very short talk on Chat has brought this easy solution:

    // is_member_function_pointer
    template<typename T> struct is_member_function_pointer : public false_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...)> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) volatile> : public true_type {};  
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const volatile> : public true_type {};
    

    Which includes specializations for volatile as well.

    EDIT as @Xeo and @Johannes pointed out, I missed the ref-qualifier (aka rvalue for *this) versions:

    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) volatile &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const volatile &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) volatile &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...) const volatile &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...)> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) volatile> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const volatile> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) volatile &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const volatile &> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) volatile &&> : public true_type {};
    template<typename T, typename Class, typename... Args> struct is_member_function_pointer<T (Class::*)(Args...,...) const volatile &&> : public true_type {};
    

    Which is still quite doable. It's clearer then crazy template magic and numerous helper templates IMHO.

    EDIT2 to clarify, the above are all in an implementation namespace and wrapped around by

    template<typename T> constexpr bool
    is_member_function_pointer() { return __implementation::is_member_function_pointer<remove_cv<T>>::result; }
    

    Where remove_cv is alias template'd to the convenient

    template<typenamen T> using
    remove_cv = typename __implementation::remove_cv<T>::type;
    

    I suppose there are other, and maybe better ways, but this one is at least clear to the reader without any further SFINAE tricks like applied in libc++ or libstdc++, IMHO.

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