• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2  (C) Copyright Edward Diener 2011,2019
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_function_templates Introspecting function templates technique]
9[#sectti_function_templates]
10
11Function templates, like functions, can be entities within a user-defined
12type. Just as functions within a user-defined type can be member functions
13or static member functions, function templates within a user-defined type
14can be member function templates or static member function templates.
15In this respect function templates are related to functions. Function templates
16represent a family of possible functions. In this respect they are similar to
17class templates, which represent a family of possible class types.
18
19The technique for introspecting class templates in the TTI library is taken
20from the implementation of the technique in the Boost MPL library. In the case
21of `BOOST_TTI_HAS_TEMPLATE` using the template type parameters form it directly
22uses the Boost MPL library functionality while in the case of `BOOST_TTI_HAS_TEMPLATE`
23using the specific form it replicates much of the technique in the Boost MPL library.
24Either technique for introspecting class templates depends directly on the fact that in
25C++ we can pass a template as a parameter to another template using what is called
26a "template template" parameter type.
27
28One obvious thing about a template template parameter type is that it is a
29class template. The fact that we can pass class templates as a template parameter but not
30function templates as a template parameter is the major factor why there is no equivalent
31method for introspecting a function template signature at compile time as there is for
32introspecting class templates signature.
33
34[heading Introspection using an instantiated function template]
35
36Although there is no way to introspect for a function template signature in TTI, there is
37an alternate way of introspecting a function template. It is possible to check whether some
38particular [*instantiation] of a nested function template exists at compile-time without
39generating a compiler error, as long as all the lower level indidual types in that instantiation
40exist at the time introspection of a function template occurs. In plainer C++ terms we call the
41instantiation of a function template "calling ( or invoking ) the function template". Although
42checking whether some particular instantiation of a nested function template exists at compile-time
43does not prove that the nested function template itself has a particular signature, since the
44instantiation itself may fail even when the nested function template does exist, it provides
45a viable way of introspecting function templates because the vast majority of function
46templates are designed to accept any type(s) and avoid compile time failure. Also when we
47introspect using a function template instantiation for a nested function template we are
48replicating how function templates are actually used in C++.
49
50To see how this works in general in the TTI library I will give an example of a nested
51function template in a user-defined type.
52
53  struct AType
54    {
55    template<class X,class Y,class Z> double AFuncTemplate(X x,Y * y,Z & z)
56      { ...some code using x,y,z; return 0.0; }
57    };
58
59The code shows a member function template within a user-defined struct called `AType`.
60Ideally what we would like to do is to be able to verify that the function template
61signature of `template<class X,class Y,class Z> double AFuncTemplate(X,Y *,Z &)`
62exists within the `AType` type, but we can not do that in TTI. If we were to call `AFuncTemplate`
63from within some functionality within the `AType` type, we would substitute some arguments
64for `X,Y *,Z &` and the C++ compiler would be able to figure out the types for X, Y, and Z
65and create a function to be called.
66
67If we look at this in terms of compile time programming ( aka template metaprogramming )
68what we are really interested in is whether there is a function template called `AFuncTemplate`
69within a type called `AType` which can be invoked with the X, Y, and Z types as some set
70of types which are equivalent to calling `AFuncTemplate` with some set of arguments. Let's suppose
71we want to call `AFuncTemplate` with an `int` value as the first argument, `long *` as the
72second argument, and a `bool &` as the third argument. In TTI introspection terms for a function
73template what we therefore are going to do is to check if we can instantiate the function
74template as:
75
76  double AFuncTemplate<int,long,bool>(int,long *,bool &)
77
78This is the form of a single possible instantiation of function template `AFuncTemplate`. When it is
79subsequently explained how to use an instantiation of a function template to check if an inner function template
80exists, this is what we mean. The instantiation itself does not exist when we introspect a function template
81but all the parts of our instantiation signature are used in the process of introspection.
82It should be realized that we could use any combination of valid types or values to create our
83theoretical instantiation of a given function template, as long as those type and/or values produces
84a valid callable function which does not contain compile time errors.
85
86The actual types and/or values we use in an instantiation of a function template we introspect
87must be declared when we do the introspection. For built-in types this is always the case.
88If we use instead, for whatever reason, a user-defined type in a given instantiation, that type
89must be declared when we invoke the metafunction which does the introspection.
90
91Further areas of the documentation will explain in its place how we use an instantiation of
92a function template to introspect respectively a member function template, a static member
93function template, or any inner function template. The technique we use is very similar to
94the way we introspect any nested entity, but instead of looking for a signature that declares
95that nested entity, with function templates we look for a signature representing some
96instantiation of the function template.
97
98[endsect]
99