Is it possible to check for existence of member templates just by an identifier?

后端 未结 4 1005
醉酒成梦
醉酒成梦 2021-01-04 11:54

Can we detect member function template, variable template, class/struct/union template or alias templ

4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-04 12:10

    I think I got it. Thanks to Aaron McDaid and vsoftco answers, I succeeded in detecting member type templates (alias template, struct template, class template and union template), member function templates with one additional drawback, and member variable templates.

    This implementation has some drawbacks:

    • Class foo that we check for existence of name bar musn't be final type.
    • Templates with mixed type/non-type/template-template parameters won't be detected.
    • Code is kinda long.

    Additional drawback is:

    • [Note: Will be fixed soon!] Checking for member function tempalates will return true, if class foo has any overloaded function bar. I just didn't have any means to detect overloaded function alone. This will also affect final has_member_template type trait.

    Here is the implementation:

    #include 
    #include 
    #include 
    
    /***Check if type is template***/
    template  class>
    constexpr bool is_template_type()
    {
        return true;
    }
    
    template 
    constexpr bool is_template_type()
    {
        return false;
    }
    
    /***Check if T has static member function "bar" ***/
    template 
    struct has_static_member_function_bar : std::false_type
    { };
    
    template 
    struct has_static_member_function_bar::type>::value
            >
        > : std::true_type
    { };
    
    /***Check if T has member function "bar" ***/
    template 
    struct has_member_function_bar : std::false_type
    { };
    
    
    template 
    struct has_member_function_bar::value
            >
        > : std::true_type
    { };
    
    /***Check if T has member reference "bar" ***/
    template 
    struct has_member_reference_bar : std::false_type
    { };
    
    template 
    struct has_member_reference_bar::value
            >
        > : std::true_type
    { };
    
    /***Check if T has static member object "bar" ***/
    template 
    struct has_static_member_object_bar : std::false_type
    { };
    
    template 
    struct has_static_member_object_bar::type>::value &&
                        (!std::is_member_object_pointer::value)
    
            >
        > : std::true_type
    { };
    
    /***Check if T has member function "bar" ***/
    template 
    struct has_member_object_bar : std::false_type
    { };
    
    template 
    struct has_member_object_bar::value
            >
        > : std::true_type
    { };
    
    /***Check if T has member alias, struct, class, union template "bar" ***/
    template 
    struct has_member_type_template_bar : std::false_type
    { };
    
    template 
    struct has_member_type_template_bar()
            >
        > : std::true_type
    { };
    
    /***Check if T has at least one name "bar" ***/
    struct has_at_least_one_bar_impl { int bar; };
    
    template
    struct bar_overloads : T , has_at_least_one_bar_impl { };
    
    template
    struct has_at_least_one_bar : std::true_type { };
    
    template
    struct has_at_least_one_bar::bar) >>
        : std::false_type { };
    
    /***Check if T has member object, reference, not-overloaded function "bar" ***/
    template 
    struct has_non_type_non_overloaded_member_bar : std::false_type
    { };
    
    template 
    struct has_non_type_non_overloaded_member_bar> : std::true_type
    { };
    
    
    /***Check if T has member function "bar" ***/
    template 
    struct has_type_member_bar : std::false_type
    { };
    
    template 
    struct has_type_member_bar> : std::true_type
    { };
    
    /***Check if T has no more than one member "bar" ***/
    template
    struct has_at_most_one_bar : std::false_type
    { };
    
    template
    struct has_at_most_one_bar::value ||
            has_non_type_non_overloaded_member_bar::value
            >
        > : std::true_type
    { };
    
    /***Check if T has member function template "bar" ***/
    template 
    struct has_member_function_template_bar : std::false_type
    { };
    
    template 
    struct has_member_function_template_bar::value &&
            (!has_member_type_template_bar::value) &&
            (!has_non_type_non_overloaded_member_bar::value) &&
            (!has_member_function_bar::value) &&
            (!has_type_member_bar::value)
            >
        > : std::true_type
    { };
    
    /***Check if T has member variable template "bar" ***/
    template 
    struct has_member_variable_template_bar : std::false_type
    { };
    
    template 
    struct has_member_variable_template_bar::value &&
            (!has_member_type_template_bar::value) &&
            (!has_member_function_template_bar::value) &&
            (!has_type_member_bar::value) &&
            (!has_static_member_function_bar::value) &&
            (!has_member_function_bar::value) &&
            (!has_member_object_bar::value) &&
            (!has_member_reference_bar::value) &&
            (!has_static_member_object_bar::value)>
        > : std::true_type
    { };
    
    /***Check if T has any member template "bar" ***/
    template 
    struct has_member_template_bar : std::false_type
    { };
    
    template 
    struct has_member_template_bar::value ||
            has_member_function_template_bar::value ||
            has_member_variable_template_bar::value>
        > : std::true_type
    { };
    

    Live example

    Example output:

    ---Has type template bar---
    consists_no_bar:                  false
    consists_alias:                   false
    consists_struct:                  false
    consists_class:                   false
    consists_union:                   false
    consists_variable:                false
    consists_function:                false
    consists_overloaded_func:         false
    consists_reference:               false
    consists_t_alias:                 true
    consists_t_struct:                true
    consists_t_class:                 true
    consists_t_union:                 true
    consists_t_variable:              false
    consists_t_function:              false
    consists_t_overloaded_function:   false
    consists_s_variable:              false
    consists_s_function:              false
    consists_s_overloaded_func:       false
    consists_s_t_function:            false
    consists_s_t_overloaded_function: false
    
    --Has member function template bar---
    consists_no_bar:                  false
    consists_alias:                   false
    consists_struct:                  false
    consists_class:                   false
    consists_union:                   false
    consists_variable:                false
    consists_function:                false
    consists_overloaded_func:         true // implmementation bug
    consists_reference:               false
    consists_t_alias:                 false
    consists_t_struct:                false
    consists_t_class:                 false
    consists_t_union:                 false
    consists_t_variable:              false
    consists_t_function:              true
    consists_t_overloaded_function:   true
    consists_s_variable:              false
    consists_s_function:              false
    consists_s_overloaded_func:       true // implmementation bug
    consists_s_t_function:            true
    consists_s_t_overloaded_function: true
    
    --Has member variable template bar---
    consists_no_bar:                  false
    consists_alias:                   false
    consists_struct:                  false
    consists_class:                   false
    consists_union:                   false
    consists_variable:                false
    consists_function:                false
    consists_overloaded_func:         false
    consists_reference:               false
    consists_t_alias:                 false
    consists_t_struct:                false
    consists_t_class:                 false
    consists_t_union:                 false
    consists_t_variable:              true
    consists_t_function:              false
    consists_t_overloaded_function:   false
    consists_s_variable:              false
    consists_s_function:              false
    consists_s_overloaded_func:       false
    consists_s_t_function:            false
    consists_s_t_overloaded_function: false
    
    --Has any member template bar---
    consists_no_bar:                  false
    consists_alias:                   false
    consists_struct:                  false
    consists_class:                   false
    consists_union:                   false
    consists_variable:                false
    consists_function:                false
    consists_overloaded_func:         true // implmementation bug
    consists_reference:               false
    consists_t_alias:                 true
    consists_t_struct:                true
    consists_t_class:                 true
    consists_t_union:                 true
    consists_t_variable:              true
    consists_t_function:              true
    consists_t_overloaded_function:   true
    consists_s_variable:              false
    consists_s_function:              false
    consists_s_overloaded_func:       true // implmementation bug
    consists_s_t_function:            true
    consists_s_t_overloaded_function: true
    

    I'm still sad that I couldn't detect overloaded functions... But it was fun :)

提交回复
热议问题