mirror of
https://github.com/boostorg/tti.git
synced 2026-02-02 21:32:08 +00:00
129 lines
6.0 KiB
Plaintext
129 lines
6.0 KiB
Plaintext
[/
|
|
(C) Copyright Edward Diener 2020
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt).
|
|
]
|
|
|
|
[section:tti_detail_has_member_function_template Introspecting member function template]
|
|
|
|
We can introspect a member function template of a user-defined type
|
|
using the TTI functionality we shall now explain.
|
|
|
|
A member function template is a function template that is a non-static memmber
|
|
of a user-defined type. An example of a member function template would be:
|
|
|
|
struct AType
|
|
{
|
|
template<class X,class Y,class Z> double AFuncTemplate(X x,Y * y,Z & z)
|
|
{ ...some code using x,y,z; return 0.0; }
|
|
};
|
|
|
|
In order to introspect the function template we use some theoretical valid instantiation of
|
|
the member function template `AFuncTemplate`. An instantiation of a function template
|
|
was previously explained in the topic [link sectti_function_templates "Introspecting function templates technique"].
|
|
|
|
For the purposes of illustration the instantiation we will use is:
|
|
|
|
double AFuncTemplate<int,long,bool>(int,long *,bool &)
|
|
|
|
What we have now which the TTI will need in order to introspect the member function
|
|
template `template<class X,class Y,class Z> double AFuncTemplate(X,Y *,Z &)`
|
|
within the `AType` struct is:
|
|
|
|
* The name of `AFuncTemplate`
|
|
* The template parameters of `int,long,bool`
|
|
* The enclosing type of `AType`
|
|
* The return type of `double`
|
|
* The function parameters of `int,long *,bool &`
|
|
|
|
[heading Generating the metafunction]
|
|
|
|
As with all TTI functionality for introspecting entities within a user-defined
|
|
type introspecting a member function template is a two step process. The first
|
|
process is using a macro to generate a metafunction. The macro for
|
|
member function templates is [macroref BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE].
|
|
This macro takes the name of the member function template and the instantiated
|
|
template parameters, the first two items in our list above:
|
|
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(AFuncTemplate,int,long,bool)
|
|
|
|
An alternative form for compilers which do not support variadic macros, and which will
|
|
also work with compilers which do support variadic macros, is to specify
|
|
the template parameters of the instantiation as a single macro argument using a
|
|
Boost PP array:
|
|
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE(AFuncTemplate,(3,(int,long,bool)))
|
|
|
|
The macro generates a metafunction based on the pattern of
|
|
"has_member_function_template_'name_of_inner_member_function_template'",
|
|
which in our example case would be `has_member_function_template_AFuncTemplate`.
|
|
|
|
[heading Invoking the metafunction]
|
|
|
|
To use this macro to test whether our member function template exists
|
|
the metafunction the macro creates is invoked with the enclosing type, the instantiated return type,
|
|
and the instantiated function parameters, with the resulting `value` being a compile time
|
|
boolean constant which is `true` if the member function template exists,
|
|
or `false` otherwise. There are two ways to do this. We can either
|
|
use each of our needed types as separate parameters, with the function parameters
|
|
being enclosed in an MPL forward sequence, or we can compose our needed type
|
|
in the form of a pointer to member function type. In the first case we would have:
|
|
|
|
has_member_function_template_AFuncTemplate<AType,double,boost::mpl::vector<int,long *,bool &> >::value
|
|
|
|
and in the second case we would have:
|
|
|
|
has_member_function_template_AFuncTemplate<double (AType::*) (int,long *,bool &)>::value
|
|
|
|
Both invocations are equivalent in functionality.
|
|
|
|
[heading Other considerations]
|
|
|
|
The macro for generating the metafunction for introspecting member function templates
|
|
also has, like other macros in the TTI library, a complex macro form where the
|
|
end-user can directly specify the name of the metafunction to be generated. The
|
|
corresponding macro is BOOST_TTI_TRAIT_HAS_MEMBER_FUNCTION_TEMPLATE,
|
|
where the first parameter is the name of the metafunction to be generated,
|
|
the second parameter is the member function template name, and the remaining parameters
|
|
are the instantiated template parameters. For our example we could have
|
|
|
|
BOOST_TTI_TRAIT_HAS_MEMBER_FUNCTION_TEMPLATE(AMetafunctionName,AFuncTemplate,int,long,bool)
|
|
|
|
or for the non-variadic macro form
|
|
|
|
BOOST_TTI_TRAIT_HAS_MEMBER_FUNCTION_TEMPLATE(AMetafunctionName,AFuncTemplate,(3,(int,long,bool)))
|
|
|
|
which generates a metafunction whose name would be `AMetafunctionName`.
|
|
|
|
In all other respects the resulting metafunction generated works exactly the same
|
|
as when using the simpler macro form previously illustrated.
|
|
|
|
If you do use the simple macro form, which generates the metafunction name
|
|
from the name of the function template you are introspecting, you can use
|
|
a corresponding macro, taking the name of the member function template as a single
|
|
parameter, to create the appropriate metafunction name if you do not want to
|
|
remember the pattern for generating the metafunction name. This macro name is
|
|
`BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE_GEN` as in
|
|
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION_TEMPLATE_GEN(AFuncTemplate)
|
|
|
|
which would generate the name `has_member_function_template_AFuncTemplate`.
|
|
|
|
When invoking the appropriate metafunction using the long form of an enclosing
|
|
type, instantiated return type, and instantiated function parameters, a fourth
|
|
template argument may optionally be given which holds a Boost FunctionTypes tag
|
|
type to specify cv-qualification. This means you can add 'const', 'volatile', or
|
|
both by specifying an appropriate tag type. An alternate to using the tag type
|
|
is to specify the enclosing type as 'const', 'volatile', or both.
|
|
As an example if you specify the tag type as
|
|
'boost::function_types::const_qualified' or if you specify the enclosing
|
|
type as 'const YourEnclosingType', the member function template which you are
|
|
introspecting must be a const function template to match correctly.
|
|
|
|
When invoking the metafunction using the shorter form of a pointer to member function
|
|
you can simply add a possible cv-qualification, such as `const`, to the end of the
|
|
pointer to member function syntax.
|
|
|
|
[endsect]
|