Can we detect member function template, variable template, class/struct/union template or alias templ
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:
foo that we check for existence of name bar musn't be final type.Additional drawback is:
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 :)