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