1[/ 2 (C) Copyright Edward Diener 2020 3 Distributed under the Boost Software License, Version 1.0. 4 (See accompanying file LICENSE_1_0.txt or copy at 5 http://www.boost.org/LICENSE_1_0.txt). 6] 7 8[section:tti_detail_has_function_template Introspecting function template] 9 10We can introspect a member function template or a static member function template 11of a user-defined type using the TTI functionality we shall now explain. 12 13A function template of a user-defined type can either be a member function 14template or a static member function template. An example would be: 15 16 struct AType 17 { 18 template<class X,class Y,class Z> double AFuncTemplate(X x,Y * y,Z & z) 19 { ...some code using x,y,z; return 0.0; } 20 template<class X,int Y> static int AFuncTemplate(X x) 21 { ...some code using x; return Y; } 22 }; 23 24A function template `AFuncTemplate` is a member function template of the `AType` 25user-defined type and a different function template also called `AFuncTemplate` 26is a static member function template of the `AType` user-defined type. 27 28In order to introspect either function template we use some theoretical valid 29instantiations of `AFuncTemplate`. An instantiation of a function template was 30previously explained in the topic [link sectti_function_templates "Introspecting function templates technique"]. 31 32For the purposes of illustration the instantiation we will use is: 33 34 double AFuncTemplate<char,bool,int>(char,bool *,int &) 35 36What we have now which the TTI will need in order to introspect the function 37template `template<class X,class Y,class Z> double AFuncTemplate(X,Y *,Z &)` 38within the `AType` struct is: 39 40* The name of `AFuncTemplate` 41* The template parameters of `char,bool,int` 42* The enclosing type of `AType` 43* The return type of `double` 44* The function parameters of `char,bool *,int &` 45 46[heading Generating the metafunction] 47 48As with all TTI functionality for introspecting entities within a user-defined 49type introspecting a function template is a two step process. The first 50process is using a macro to generate a metafunction. The macro for 51function templates is [macroref BOOST_TTI_HAS_FUNCTION_TEMPLATE]. 52This macro takes the name of the member function template and the instantiated 53template parameters, the first two items in our list above: 54 55 BOOST_TTI_HAS_FUNCTION_TEMPLATE(AFuncTemplate,char,bool,int) 56 57An alternative form for compilers which do not support variadic macros, and which will 58also work with compilers which do support variadic macros, is to specify 59the template parameters of the instantiation as a single macro argument using a 60Boost PP array: 61 62 BOOST_TTI_HAS_FUNCTION_TEMPLATE(AFuncTemplate,(3,(char,bool,int))) 63 64The macro generates a metafunction based on the pattern of 65"has_function_template_'name_of_inner_function_template'", 66which in our example case would be `has_function_template_AFuncTemplate`. 67 68[heading Invoking the metafunction] 69 70To use this macro to test whether our function template exists 71the metafunction the macro creates is invoked with the enclosing type, the instantiated return type, 72and the instantiated function parameters, with the resulting `value` being a compile time 73boolean constant which is `true` if the function template exists, 74or `false` otherwise. We use each of our needed types as separate parameters, with the 75function parameters being enclosed in an MPL forward sequence. We would have: 76 77 has_function_template_AFuncTemplate<AType,double,boost::mpl::vector<char,bool *,int &> >::value 78 79[heading Introspecting the other function template] 80 81If we chose to try to introspect the second `AFuncTemplate` within `AType` we might 82choose an instantiation of: 83 84 int AFuncTemplate<long,7435>(long) 85 86Our generation of the metafunction would then be: 87 88 BOOST_TTI_HAS_FUNCTION_TEMPLATE(AFuncTemplate,long,7435) 89 90or 91 92 BOOST_TTI_HAS_FUNCTION_TEMPLATE(AFuncTemplate,(2,(long,7435))) 93 94and our invocation of the metafunction would now be: 95 96 has_function_template_AFuncTemplate<AType,int,boost::mpl::vector<long> >::value 97 98[heading Other considerations] 99 100In our two examples above we could not introspect both function templates 101in the same namespace using the BOOST_TTI_HAS_FUNCTION_TEMPLATE macro as we would 102be generating two metafunctions with the same name, which would be 103`has_function_template_AFuncTemplate`, thus violating the One Definition Rule. 104The solution to this is the use of the complex macro form. 105 106The macro for generating the metafunction for introspecting function templates 107also has, like other macros in the TTI library, a complex macro form where the 108end-user can directly specify the name of the metafunction to be generated. The 109corresponding macro is BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE, 110where the first parameter is the name of the metafunction to be generated, 111the second parameter is the member function template name, and the remaining parameters 112are the instantiated template parameters. 113 114For our first example we could have 115 116 BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(FirstMetafunction,char,bool,int) 117 118or for the non-variadic macro form 119 120 BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(FirstMetafunction,(3,(char,bool,int))) 121 122which generates a metafunction whose name would be `FirstMetafunction`. 123 124For our second example we could have 125 126 BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(SecondMetafunction,AFuncTemplate,long,7435) 127 128or for the non-variadic macro form 129 130 BOOST_TTI_TRAIT_HAS_FUNCTION_TEMPLATE(SecondMetafunction,AFuncTemplate,(2,(long,7435))) 131 132which generates a metafunction whose name would be `SecondMetafunction`. 133 134In all other respects the resulting metafunctions generated works exactly the same 135as when using the simpler macro form previously illustrated. 136 137If you do use the simple macro form, which generates the metafunction name 138from the name of the function template you are introspecting, you can use 139a corresponding macro, taking the name of the function template as a single 140parameter, to create the appropriate metafunction name if you do not want to 141remember the pattern for generating the metafunction name. This macro name is 142`BOOST_TTI_HAS_FUNCTION_TEMPLATE_GEN` as in 143 144 BOOST_TTI_HAS_FUNCTION_TEMPLATE_GEN(AFuncTemplate) 145 146which would generate the name `has_function_template_AFuncTemplate`. 147 148When invoking the appropriate metafunction a fourth 149template argument may optionally be given which holds a Boost FunctionTypes tag 150type. This optional template argument is of much less use for 151function templates than for non-static member function templates since static 152member function templates, like static member functions, can not have 153cv-qualifications. which a number of Boost FunctionTypes tags provide. 154Nonetheless this optional Boost FunctionTypes tag is available for 155end-user use and may come in handy in certain rare cases, as when some calling 156convention qualification for the function template needs to be 157specified. If you do use a Boost FunctionTypes tag type for cv-qualification, 158such as `boost::function_types::const_qualified` to look for a function template 159it will be applied when introspecting for the member function template side of 160the match, but will ensure that introspecting for the static member function 161template side of the match will always fail. In either case no compiler error 162will be generated. 163 164[endsect] 165