]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | (C) Copyright Edward Diener 2011,2012,2014 | |
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_member_function Introspecting member function] | |
9 | ||
10 | The TTI macro [macroref BOOST_TTI_HAS_MEMBER_FUNCTION] introspects | |
11 | a member function of a class. | |
12 | ||
13 | BOOST_TTI_HAS_MEMBER_FUNCTION takes a single | |
14 | parameter which is the name of an inner member function whose existence | |
15 | the programmer wants to check. The macro generates a metafunction | |
16 | called 'has_member_function_'name_of_inner_member_function'. | |
17 | ||
18 | The metafunction can be invoked in two different ways. | |
19 | ||
20 | The first way of invoking the metafunction is by passing it the enclosing | |
21 | type to introspect and a signature for the member function as a series of | |
22 | separate template arguments. The signature for the member function consists | |
23 | of the template arguments of a return type, of optional parameter types in | |
24 | the form of a boost::mpl forward sequence of types, and of an optional Boost | |
25 | FunctionTypes tag type. A typical boost::mpl forward sequence of types is | |
26 | a boost::mpl::vector<>. | |
27 | ||
28 | The optional Boost FunctionTypes tag type may be used to specify | |
29 | cv-qualification. This means you can add 'const', 'volatile', or both by | |
30 | specifying an appropriate tag type. An alternate to using the tag type | |
31 | is to specify the enclosing type as 'const', 'volatile', or both. | |
32 | As an example if you specify the tag type as | |
33 | 'boost::function_types::const_qualified' or if you specify the enclosing | |
34 | type as 'const T', the member function which you are introspecting | |
35 | must be a const function. | |
36 | ||
37 | The second way of invoking the metafunction is by passing it a single | |
38 | parameter, which is a pointer to member function. This type has the form of: | |
39 | ||
40 | Return_Type ( Enclosing_Type::* ) ( Parameter_Types ) cv_qualifier(s) | |
41 | ||
42 | where the Parameter_Types may be empty, or a comma-separated | |
43 | list of parameter types if there are more than one parameter type. | |
44 | The cv-qualifier may be 'const', 'volatile', or 'const volatile'. | |
45 | ||
46 | The metafunction returns a single type called 'type', which is a | |
47 | boost::mpl::bool_. As a convenience the metafunction | |
48 | returns the value of this type directly as a compile time bool constant | |
49 | called 'value'. This 'value' is true or false depending on whether the inner | |
50 | member function, of the specified signature, exists or not. | |
51 | ||
52 | [heading Generating the metafunction] | |
53 | ||
54 | You generate the metafunction by invoking the macro with the name | |
55 | of an inner member function: | |
56 | ||
57 | BOOST_TTI_HAS_MEMBER_FUNCTION(AMemberFunction) | |
58 | ||
59 | generates a metafunction called 'has_member_function_AMemberFunction' in the current scope. | |
60 | ||
61 | [heading Invoking the metafunction] | |
62 | ||
63 | You invoke the metafunction by instantiating the template with an enclosing | |
64 | type to introspect and the signature of the member function as a series of template | |
65 | parameters. Alternatively you can invoke the metafunction by passing it a single | |
66 | type which is a pointer to member function. | |
67 | ||
68 | A return value called 'value' is a compile time bool constant. | |
69 | ||
70 | has_member_function_AMemberFunction | |
71 | < | |
72 | Enclosing_Type, | |
73 | MemberFunction_ReturnType, | |
74 | boost::mpl::vector<MemberFunction_ParameterTypes>, // optional, can be any mpl forward sequence | |
75 | boost::function_types::SomeTagType // optional, can be any FunctionTypes tag type | |
76 | >::value | |
77 | ||
78 | OR | |
79 | ||
80 | has_member_function_AMemberFunction | |
81 | < | |
82 | MemberFunction_ReturnType (Enclosing_Type::*) (MemberFunction_ParameterTypes) optional_cv_qualification | |
83 | >::value | |
84 | ||
85 | [heading Examples] | |
86 | ||
87 | First we generate metafunctions for various inner member function names: | |
88 | ||
89 | #include <boost/tti/has_member_function.hpp> | |
90 | ||
91 | BOOST_TTI_HAS_MEMBER_FUNCTION(function1) | |
92 | BOOST_TTI_HAS_MEMBER_FUNCTION(function2) | |
93 | BOOST_TTI_HAS_MEMBER_FUNCTION(function3) | |
94 | ||
95 | Next let us create some user-defined types we want to introspect. | |
96 | ||
97 | struct AClass | |
98 | { | |
99 | }; | |
100 | struct Top | |
101 | { | |
102 | int function1(); | |
103 | AClass function2(double,short *); | |
104 | }; | |
105 | struct Top2 | |
106 | { | |
107 | long function2(Top &,int,bool,short,float); | |
108 | Top * function3(long,int,AClass &); | |
109 | }; | |
110 | ||
111 | Finally we invoke our metafunction and return our value. | |
112 | This all happens at compile time, and can be used by | |
113 | programmers doing compile time template metaprogramming. | |
114 | ||
115 | We will show both forms in the following examples. | |
116 | Both forms are completely interchangeable as to the result | |
117 | desired. | |
118 | ||
119 | has_member_function_function1<Top,int>::value; // true | |
120 | has_member_function_function1<Top,int,boost::mpl::vector<> >::value; // true | |
121 | has_member_function_function1<Top2,int>::value; // false | |
122 | ||
123 | has_member_function_function2<AClass (Top::*) (double,short *)>::value; // true | |
124 | has_member_function_function2<AClass (Top2::*) (double,short *)>::value; // false | |
125 | has_member_function_function2<long (Top2::*) (Top &,int,bool,short,float)>::value; // true | |
126 | ||
127 | has_member_function_function3<int (Top2::*) ()>::value; // false | |
128 | has_member_function_function3<Top2,Top *,boost::mpl::vector<long,int,AClass &> >::value; // true; | |
129 | ||
130 | [heading Metafunction re-use] | |
131 | ||
132 | The macro encodes only the name of the member function for which | |
133 | we are searching and the fact that we are introspecting for a | |
134 | member function within an enclosing type. | |
135 | ||
136 | Because of this, once we create our metafunction for | |
137 | introspecting a member function by name, we can reuse the | |
138 | metafunction for introspecting any enclosing type, having any | |
139 | member function, for that name. | |
140 | ||
141 | [endsect] |