Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / type_traits / doc / common_type.qbk
1 [/ 
2   Copyright 2008 Howard Hinnant
3   Copyright 2008 Beman Dawes
4   Copyright 2010 John Maddock
5   Distributed under the Boost Software License, Version 1.0.
6   (See accompanying file LICENSE_1_0.txt or copy at
7   http://www.boost.org/LICENSE_1_0.txt).
8 ]
9
10 [/===================================================================]
11 [section:common_type common_type]
12 [/===================================================================]
13
14 [def __declval [@../../../utility/doc/html/declval.html declval]]
15
16
17 __header ` #include <boost/type_traits/common_type.hpp>` or ` #include <boost/type_traits.hpp>`
18
19     namespace boost {
20       template <class ...T>  struct __common_type;
21     }
22
23
24 __common_type is a traits class used to deduce a type common to a several types, useful as the return type of functions 
25 operating on multiple input types such as in mixed-mode arithmetic..
26
27 The nested typedef `::type` could be defined as follows:
28
29     template <class ...T>
30     struct common_type;
31     
32     template <class T, class U, class ...V>
33     struct common_type<T,U,...V> {
34         typedef typename __common_type<typename __common_type<T, U>::type, V...>::type type;
35     };
36
37     template <class T>
38     struct common_type<T> {
39         typedef T type;
40     };
41
42     template <class T, class U>
43     struct common_type<T, U> {
44         typedef decltype(__declval<bool>() ? __declval<T>() : __declval<U>()) type;
45     };
46
47 All parameter types must be complete. This trait is permitted to be specialized by a user if at least one 
48 template parameter is a user-defined type. [*Note:] Such specializations are required when only explicit conversions 
49 are desired among the __common_type arguments.
50
51 Note that when the compiler does not support variadic templates (and the macro BOOST_NO_VARIADIC_TEMPLATES is defined)
52 then the maximum number of template arguments is 3.
53
54
55 [h4 Configuration macros]
56
57 When the compiler does not support static assertions then the user can select the way static assertions are reported. Define
58
59 * BOOST_COMMON_TYPE_USES_STATIC_ASSERT: define it if you want to use Boost.StaticAssert
60 * BOOST_COMMON_TYPE_USES_MPL_ASSERT: define it if you want to use Boost.MPL static assertions
61
62 The default behavior is to use mpl assertions in this case, but setting BOOST_COMMON_TYPE_USES_STATIC_ASSERT may reduce
63 compile times and header dependencies somewhat.
64
65 Depending on the static assertion used you will have an hint of the failing assertion either through the symbol or through the text.
66
67 When possible common_type is implemented using `decltype`. Otherwise when BOOST_COMMON_TYPE_DONT_USE_TYPEOF is not defined 
68 it uses Boost.TypeOf.
69
70 [h4 Tutorial]
71
72 In a nutshell, __common_type is a trait that takes 1 or more types, and returns a type which 
73 all of the types will convert to. The default definition demands this conversion be implicit. 
74 However the trait can be specialized for user-defined types which want to limit their inter-type conversions to explicit, 
75 and yet still want to interoperate with the __common_type facility.
76
77 [*Example:]
78
79     template <class T, class U>
80     complex<typename __common_type<T, U>::type>
81     operator+(complex<T>, complex<U>);
82
83
84 In the above example, "mixed-mode" complex arithmetic is allowed. The return type is described by __common_type. 
85 For example the resulting type of adding a `complex<float>` and `complex<double>` might be a `complex<double>`. 
86
87 Here is how someone might produce a variadic comparison function:
88
89     template <class ...T>
90     typename __common_type<T...>::type
91     min(T... t);
92
93 This is a very useful and broadly applicable utility. 
94
95 [h4 How to get the common type of types with explicit conversions?]
96
97 Another choice for the author of the preceding operator could be
98
99     template <class T, class U>
100     typename __common_type<complex<T>, complex<U> >::type
101     operator+(complex<T>, complex<U>);
102
103 As the default definition of __common_type demands the conversion be implicit, we need to specialize the trait for complex types as follows.
104
105     template <class T, class U>
106     struct __common_type<complex<T>, complex<U> > {
107         typedef complex< __common_type<T, U> > type;
108     };
109
110 [h4 How important is the order of the common_type<> template arguments?]
111
112 The order of the template parameters is important. 
113
114 `common_type<A,B,C>::type` is not equivalent to `common_type<C,A,B>::type`, but to `common_type<common_type<A,B>::type, C>::type`.
115
116 Consider
117
118     struct A {};
119     struct B {};
120     struct C {
121         C() {}
122         C(A const&) {}
123         C(B const&) {}
124         C& operator=(C const&) {
125             return *this;
126         }
127     };
128
129 The following doesn't compile
130
131     typedef boost::common_type<A, B, C>::type ABC; // Does not compile
132
133 while 
134
135     typedef boost::common_type<C, A, B>::type ABC;
136
137 compiles.
138
139 Thus, as `common_type<A,B>::type` is undefined,  `common_type<A,B,C>::type` is also undefined.
140
141 It is intended that clients who wish for `common_type<A, B>` to be well
142 defined to define it themselves:
143
144     namespace boost
145     {
146
147     template <>
148     struct common_type<A, B> {typedef C type;};
149
150     } 
151
152 Now this client can ask for `common_type<A, B, C>` (and get
153 the same answer).
154
155 Clients wanting to ask `common_type<A, B, C>` in any order and get the same result need to add in addition:
156
157     namespace boost
158     {
159
160     template <> struct common_type<B, A>
161     : public common_type<A, B> {};
162
163     } 
164
165 This is needed as the specialization of `common_type<A, B>` is not be used implicitly for `common_type<B, A>`.
166
167 [h4 Can the common_type of two types be a third type?]
168
169 Given the preceding example, one might expect `common_type<A,B>::type` to be `C` without any intervention from the user. 
170 But the default `common_type<>` implementation doesn't grant that. It is intended that clients who wish for `common_type<A, B>` 
171 to be well defined to define it themselves:
172
173     namespace boost
174     {
175
176     template <>
177     struct common_type<A, B> {typedef C type;};
178
179     template <> struct common_type<B, A>
180     : public common_type<A, B> {};
181
182     } 
183
184 Now this client can ask for `common_type<A, B>`.
185
186 [h4 How common_type behaves with pointers?]
187
188 Consider
189
190     struct C { }:
191     struct B : C { };
192     struct A : C { };
193
194
195 Shouldn't `common_type<A*,B*>::type` be `C*`? I would say yes, but the default implementation will make it ill-formed.
196
197 The library could add a specialization for pointers, as
198
199     namespace boost
200     {
201
202         template <typename A, typename B>
203         struct common_type<A*, B*> {
204             typedef common_type<A, B>* type;
205         };
206     }
207     
208 But in the absence of a motivating use cases, we prefer not to add more than the standard specifies. 
209
210 Of course the user can always make this specialization.
211
212 [h4 Can you explain the pros/cons of common_type against Boost.Typeof?]
213
214 Even if they appear to be close, `__common_type` and `typeof` have
215 different purposes. You use `typeof` to get the type of an expression, while
216 you use __common_type to set explicitly the type returned of a template
217 function. Both are complementary, and indeed __common_type is equivalent to 
218 `decltype(__declval<bool>() ? __declval<T>() : __declval<U>())` 
219
220 __common_type is also similar to promote_args<class ...T> in boost/math/tools/promotion.hpp, 
221 though it is not exactly the same as promote_args either.  __common_type<T1, T2>::type simply represents the result of some 
222 operation on T1 and T2, and defaults to the type obtained by putting T1 and T2 into a conditional statement.
223
224 It is meant to be customizable (via specialization) if this default is not appropriate.
225
226 [endsect]
227