142 lines
5.3 KiB
Plaintext
142 lines
5.3 KiB
Plaintext
[/
|
|
(C) Copyright Edward Diener 2011,2012,2014
|
|
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 Introspecting member function]
|
|
|
|
The TTI macro [macroref BOOST_TTI_HAS_MEMBER_FUNCTION] introspects
|
|
a member function of a class.
|
|
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION takes a single
|
|
parameter which is the name of an inner member function whose existence
|
|
the programmer wants to check. The macro generates a metafunction
|
|
called "has_member_function_'name_of_inner_member_function'".
|
|
|
|
The metafunction can be invoked in two different ways.
|
|
|
|
The first way of invoking the metafunction is by passing it the enclosing
|
|
type to introspect and a signature for the member function as a series of
|
|
separate template arguments. The signature for the member function consists
|
|
of the template arguments of a return type, of optional parameter types in
|
|
the form of a boost::mpl forward sequence of types, and of an optional Boost
|
|
FunctionTypes tag type. A typical boost::mpl forward sequence of types is
|
|
a boost::mpl::vector<>.
|
|
|
|
The optional Boost FunctionTypes tag type may be used 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 T', the member function which you are introspecting
|
|
must be a const function.
|
|
|
|
The second way of invoking the metafunction is by passing it a single
|
|
parameter, which is a pointer to member function. This type has the form of:
|
|
|
|
Return_Type ( Enclosing_Type::* ) ( Parameter_Types ) cv_qualifier(s)
|
|
|
|
where the Parameter_Types may be empty, or a comma-separated
|
|
list of parameter types if there are more than one parameter type.
|
|
The cv-qualifier may be 'const', 'volatile', or 'const volatile'.
|
|
|
|
The metafunction returns a single type called 'type', which is a
|
|
boost::mpl::bool_. As a convenience the metafunction
|
|
returns the value of this type directly as a compile time bool constant
|
|
called 'value'. This 'value' is true or false depending on whether the inner
|
|
member function, of the specified signature, exists or not.
|
|
|
|
[heading Generating the metafunction]
|
|
|
|
You generate the metafunction by invoking the macro with the name
|
|
of an inner member function:
|
|
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION(AMemberFunction)
|
|
|
|
generates a metafunction called 'has_member_function_AMemberFunction' in the current scope.
|
|
|
|
[heading Invoking the metafunction]
|
|
|
|
You invoke the metafunction by instantiating the template with an enclosing
|
|
type to introspect and the signature of the member function as a series of template
|
|
parameters. Alternatively you can invoke the metafunction by passing it a single
|
|
type which is a pointer to member function.
|
|
|
|
A return value called 'value' is a compile time bool constant.
|
|
|
|
has_member_function_AMemberFunction
|
|
<
|
|
Enclosing_Type,
|
|
MemberFunction_ReturnType,
|
|
boost::mpl::vector<MemberFunction_ParameterTypes>, // optional, can be any mpl forward sequence
|
|
boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type
|
|
>::value
|
|
|
|
OR
|
|
|
|
has_member_function_AMemberFunction
|
|
<
|
|
MemberFunction_ReturnType (Enclosing_Type::*) (MemberFunction_ParameterTypes) optional_cv_qualification
|
|
>::value
|
|
|
|
[heading Examples]
|
|
|
|
First we generate metafunctions for various inner member function names:
|
|
|
|
#include <boost/tti/has_member_function.hpp>
|
|
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION(function1)
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION(function2)
|
|
BOOST_TTI_HAS_MEMBER_FUNCTION(function3)
|
|
|
|
Next let us create some user-defined types we want to introspect.
|
|
|
|
struct AClass
|
|
{
|
|
};
|
|
struct Top
|
|
{
|
|
int function1();
|
|
AClass function2(double,short *);
|
|
};
|
|
struct Top2
|
|
{
|
|
long function2(Top &,int,bool,short,float);
|
|
Top * function3(long,int,AClass &);
|
|
};
|
|
|
|
Finally we invoke our metafunction and return our value.
|
|
This all happens at compile time, and can be used by
|
|
programmers doing compile time template metaprogramming.
|
|
|
|
We will show both forms in the following examples.
|
|
Both forms are completely interchangeable as to the result
|
|
desired.
|
|
|
|
has_member_function_function1<Top,int>::value; // true
|
|
has_member_function_function1<Top,int,boost::mpl::vector<> >::value; // true
|
|
has_member_function_function1<Top2,int>::value; // false
|
|
|
|
has_member_function_function2<AClass (Top::*) (double,short *)>::value; // true
|
|
has_member_function_function2<AClass (Top2::*) (double,short *)>::value; // false
|
|
has_member_function_function2<long (Top2::*) (Top &,int,bool,short,float)>::value; // true
|
|
|
|
has_member_function_function3<int (Top2::*) ()>::value; // false
|
|
has_member_function_function3<Top2,Top *,boost::mpl::vector<long,int,AClass &> >::value; // true;
|
|
|
|
[heading Metafunction re-use]
|
|
|
|
The macro encodes only the name of the member function for which
|
|
we are searching and the fact that we are introspecting for a
|
|
member function within an enclosing type.
|
|
|
|
Because of this, once we create our metafunction for
|
|
introspecting a member function by name, we can reuse the
|
|
metafunction for introspecting any enclosing type, having any
|
|
member function, for that name.
|
|
|
|
[endsect]
|