• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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