• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Operator Type Traits</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../../../index.html" title="Chapter 1. Boost.TypeTraits">
8<link rel="up" href="../value_traits.html" title="Type Traits that Describe the Properties of a Type">
9<link rel="prev" href="relate.html" title="Relationships Between Two Types">
10<link rel="next" href="../transform.html" title="Type Traits that Transform One Type to Another">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="relate.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../value_traits.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../transform.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h4 class="title">
27<a name="boost_typetraits.category.value_traits.operators"></a><a class="link" href="operators.html" title="Operator Type Traits">Operator
28        Type Traits</a>
29</h4></div></div></div>
30<h6>
31<a name="boost_typetraits.category.value_traits.operators.h0"></a>
32          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.introduction"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.introduction">Introduction</a>
33        </h6>
34<p>
35          These traits are all <span class="emphasis"><em>value traits</em></span> inheriting from
36          <a class="link" href="../../reference/integral_constant.html" title="integral_constant">integral_constant</a>
37          and providing a simple <code class="computeroutput"><span class="keyword">true</span></code>
38          or <code class="computeroutput"><span class="keyword">false</span></code> boolean <code class="computeroutput"><span class="identifier">value</span></code> which reflects the fact that given
39          types can or cannot be used with given operators.
40        </p>
41<p>
42          For example, <code class="computeroutput"><span class="identifier">has_plus</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
43          is a <code class="computeroutput"><span class="keyword">bool</span></code> which value is
44          <code class="computeroutput"><span class="keyword">true</span></code> because it is possible
45          to add a <code class="computeroutput"><span class="keyword">double</span></code> to an <code class="computeroutput"><span class="keyword">int</span></code> like in the following code:
46</p>
47<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
48<span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span>
49<span class="identifier">i</span><span class="special">+</span><span class="identifier">d</span><span class="special">;</span>
50</pre>
51<p>
52          It is also possible to know if the result of the operator can be used as
53          function argument of a given type. For example, <code class="computeroutput"><span class="identifier">has_plus</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">float</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
54          is <code class="computeroutput"><span class="keyword">true</span></code> because it is possible
55          to add a <code class="computeroutput"><span class="keyword">double</span></code> to an <code class="computeroutput"><span class="keyword">int</span></code> and the result (<code class="computeroutput"><span class="keyword">double</span></code>)
56          can be converted to a <code class="computeroutput"><span class="keyword">float</span></code>
57          argument like in the following code:
58</p>
59<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">float</span><span class="special">)</span> <span class="special">{</span> <span class="special">};</span>
60<span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
61<span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span>
62<span class="identifier">f</span><span class="special">(</span><span class="identifier">i</span><span class="special">+</span><span class="identifier">d</span><span class="special">);</span>
63</pre>
64<p>
65        </p>
66<h6>
67<a name="boost_typetraits.category.value_traits.operators.h1"></a>
68          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.example_of_application"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.example_of_application">Example
69          of application</a>
70        </h6>
71<p>
72          These traits can be useful to optimize the code for types supporting given
73          operations. For example a function <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">advance</span></code>
74          that increases an iterator of a given number of steps could be implemented
75          as follows:
76        </p>
77<p>
78</p>
79<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_plus_assign</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
80
81<span class="keyword">namespace</span> <span class="identifier">detail</span> <span class="special">{</span>
82<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">has_plus_assign</span> <span class="special">&gt;</span>
83<span class="keyword">struct</span> <span class="identifier">advance_impl</span><span class="special">;</span>
84
85<span class="comment">// this is used if += exists (efficient)</span>
86<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span> <span class="special">&gt;</span>
87<span class="keyword">struct</span> <span class="identifier">advance_impl</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="keyword">true</span><span class="special">&gt;</span> <span class="special">{</span>
88   <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Iterator</span> <span class="special">&amp;</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">Distance</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
89      <span class="identifier">i</span><span class="special">+=</span><span class="identifier">n</span><span class="special">;</span>
90   <span class="special">}</span>
91<span class="special">};</span>
92
93<span class="comment">// this is use if += does not exists (less efficient but cannot do better)</span>
94<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span> <span class="special">&gt;</span>
95<span class="keyword">struct</span> <span class="identifier">advance_impl</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="keyword">false</span><span class="special">&gt;</span> <span class="special">{</span>
96   <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Iterator</span> <span class="special">&amp;</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">Distance</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
97      <span class="keyword">if</span> <span class="special">(</span><span class="identifier">n</span><span class="special">&gt;</span><span class="number">0</span><span class="special">)</span> <span class="special">{</span>
98         <span class="keyword">while</span> <span class="special">(</span><span class="identifier">n</span><span class="special">--)</span> <span class="special">++</span><span class="identifier">i</span><span class="special">;</span>
99      <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
100         <span class="keyword">while</span> <span class="special">(</span><span class="identifier">n</span><span class="special">++)</span> <span class="special">--</span><span class="identifier">i</span><span class="special">;</span>
101      <span class="special">}</span>
102   <span class="special">}</span>
103<span class="special">};</span>
104<span class="special">}</span> <span class="comment">// namespace detail</span>
105
106<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Distance</span> <span class="special">&gt;</span>
107<span class="keyword">inline</span> <span class="keyword">void</span> <span class="identifier">advance</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="special">&amp;</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">Distance</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">{</span>
108   <span class="identifier">detail</span><span class="special">::</span><span class="identifier">advance_impl</span><span class="special">&lt;</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Distance</span><span class="special">,</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_plus_assign</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">&gt;::</span><span class="identifier">value</span> <span class="special">&gt;()(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">n</span><span class="special">);</span>
109<span class="special">}</span>
110</pre>
111<p>
112        </p>
113<p>
114          Then the compiler chooses the most efficient implementation according to
115          the type's ability to perform <code class="computeroutput"><span class="special">+=</span></code>
116          operation:
117        </p>
118<p>
119</p>
120<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
121
122<span class="keyword">class</span> <span class="identifier">with</span> <span class="special">{</span>
123      <span class="keyword">int</span> <span class="identifier">m_i</span><span class="special">;</span>
124   <span class="keyword">public</span><span class="special">:</span>
125      <span class="identifier">with</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_i</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
126      <span class="identifier">with</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">+=(</span><span class="keyword">int</span> <span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">m_i</span><span class="special">+=</span><span class="identifier">rhs</span><span class="special">;</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span>
127      <span class="keyword">operator</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_i</span><span class="special">;</span> <span class="special">}</span>
128<span class="special">};</span>
129
130<span class="keyword">class</span> <span class="identifier">without</span> <span class="special">{</span>
131      <span class="keyword">int</span> <span class="identifier">m_i</span><span class="special">;</span>
132   <span class="keyword">public</span><span class="special">:</span>
133      <span class="identifier">without</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">m_i</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="special">}</span>
134      <span class="identifier">without</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">++()</span> <span class="special">{</span> <span class="special">++</span><span class="identifier">m_i</span><span class="special">;</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span>
135      <span class="identifier">without</span> <span class="special">&amp;</span><span class="keyword">operator</span><span class="special">--()</span> <span class="special">{</span> <span class="special">--</span><span class="identifier">m_i</span><span class="special">;</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span>
136      <span class="keyword">operator</span> <span class="keyword">int</span> <span class="keyword">const</span> <span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_i</span><span class="special">;</span> <span class="special">}</span>
137<span class="special">};</span>
138
139<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
140   <span class="identifier">with</span> <span class="identifier">i</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
141   <span class="identifier">advance</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span> <span class="comment">// uses +=</span>
142   <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;</span><span class="string">"with: "</span><span class="special">&lt;&lt;</span><span class="identifier">i</span><span class="special">&lt;&lt;</span><span class="char">'\n'</span><span class="special">;</span>
143   <span class="identifier">without</span> <span class="identifier">j</span><span class="special">=</span><span class="number">0</span><span class="special">;</span>
144   <span class="identifier">advance</span><span class="special">(</span><span class="identifier">j</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span> <span class="comment">// uses ++</span>
145   <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;</span><span class="string">"without: "</span><span class="special">&lt;&lt;</span><span class="identifier">j</span><span class="special">&lt;&lt;</span><span class="char">'\n'</span><span class="special">;</span>
146   <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
147<span class="special">}</span>
148</pre>
149<p>
150        </p>
151<h6>
152<a name="boost_typetraits.category.value_traits.operators.h2"></a>
153          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.description"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.description">Description</a>
154        </h6>
155<p>
156          The syntax is the following:
157</p>
158<pre class="programlisting"><span class="keyword">template</span> <code class="computeroutput"><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">&gt;</span></code> <span class="identifier">has_op</span><span class="special">;</span> <span class="comment">// prefix operator</span>
159<span class="keyword">template</span> <code class="computeroutput"><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">&gt;</span></code> <span class="identifier">has_op</span><span class="special">;</span> <span class="comment">// postfix operator</span>
160<span class="keyword">template</span> <code class="computeroutput"><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Rhs</span><span class="special">=</span><span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">&gt;</span></code> <span class="identifier">has_op</span><span class="special">;</span> <span class="comment">// binary operator</span>
161</pre>
162<p>
163          where:
164        </p>
165<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
166<li class="listitem">
167              op represents the operator name
168            </li>
169<li class="listitem">
170              <code class="computeroutput"><span class="identifier">Lhs</span></code> is the type used
171              at the left hand side of <code class="computeroutput"><span class="keyword">operator</span>
172              <span class="identifier">op</span></code>,
173            </li>
174<li class="listitem">
175              <code class="computeroutput"><span class="identifier">Rhs</span></code> is the type used
176              at the right hand side of <code class="computeroutput"><span class="keyword">operator</span>
177              <span class="identifier">op</span></code>,
178            </li>
179<li class="listitem">
180              <code class="computeroutput"><span class="identifier">Ret</span></code> is the type for
181              which we want to know if the result of <code class="computeroutput"><span class="keyword">operator</span>
182              <span class="identifier">op</span></code> can be converted to.
183            </li>
184</ul></div>
185<p>
186          The default behaviour (<code class="computeroutput"><span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span></code>)
187          is to not check for the return value of the operator. If <code class="computeroutput"><span class="identifier">Ret</span></code> is different from the default <code class="computeroutput"><span class="identifier">dont_care</span></code>, the return value is checked
188          to be convertible to <code class="computeroutput"><span class="identifier">Ret</span></code>.
189          Convertible to <code class="computeroutput"><span class="identifier">Ret</span></code> means
190          that the return value can be used as argument to a function expecting
191          <code class="computeroutput"><span class="identifier">Ret</span></code>:
192</p>
193<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">Ret</span><span class="special">);</span>
194<span class="identifier">Lhs</span> <span class="identifier">lhs</span><span class="special">;</span>
195<span class="identifier">Rhs</span> <span class="identifier">rhs</span><span class="special">;</span>
196<span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">+</span><span class="identifier">rhs</span><span class="special">);</span> <span class="comment">// is valid if has_plus&lt;Lhs, Rhs, Ret&gt;::value==true</span>
197</pre>
198<p>
199          If <code class="computeroutput"><span class="identifier">Ret</span><span class="special">=</span><span class="keyword">void</span></code>, the return type is checked to be exactly
200          <code class="computeroutput"><span class="keyword">void</span></code>.
201        </p>
202<p>
203          The following tables give the list of supported binary, prefix and postfix
204          operators.
205        </p>
206<div class="table">
207<a name="boost_typetraits.category.value_traits.operators.supported_prefix_operators"></a><p class="title"><b>Table 1.4. Supported prefix operators</b></p>
208<div class="table-contents"><table class="table" summary="Supported prefix operators">
209<colgroup>
210<col>
211<col>
212</colgroup>
213<thead><tr>
214<th>
215                  <p>
216                    prefix operator
217                  </p>
218                </th>
219<th>
220                  <p>
221                    trait name
222                  </p>
223                </th>
224</tr></thead>
225<tbody>
226<tr>
227<td>
228                  <p>
229                    <code class="computeroutput"><span class="special">!</span></code>
230                  </p>
231                </td>
232<td>
233                  <p>
234                    <a class="link" href="../../reference/has_logical_not.html" title="has_logical_not"><code class="computeroutput"><span class="identifier">has_logical_not</span></code></a> <code class="computeroutput"><span class="special">&lt;</span> <span class="keyword">class</span>
235                    <span class="identifier">Rhs</span><span class="special">,</span>
236                    <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span>
237                    <span class="special">&gt;</span></code>
238                  </p>
239                </td>
240</tr>
241<tr>
242<td>
243                  <p>
244                    <code class="computeroutput"><span class="special">+</span></code>
245                  </p>
246                </td>
247<td>
248                  <p>
249                    <a class="link" href="../../reference/has_unary_plus.html" title="has_unary_plus"><code class="computeroutput"><span class="identifier">has_unary_plus</span></code></a>
250                  </p>
251                </td>
252</tr>
253<tr>
254<td>
255                  <p>
256                    <code class="computeroutput"><span class="special">-</span></code>
257                  </p>
258                </td>
259<td>
260                  <p>
261                    <a class="link" href="../../reference/has_unary_minus.html" title="has_unary_minus"><code class="computeroutput"><span class="identifier">has_unary_minus</span></code></a> and
262                    <a class="link" href="../../reference/has_negate.html" title="has_negate"><code class="computeroutput"><span class="identifier">has_negate</span></code></a>
263                  </p>
264                </td>
265</tr>
266<tr>
267<td>
268                  <p>
269                    <code class="computeroutput"><span class="special">~</span></code>
270                  </p>
271                </td>
272<td>
273                  <p>
274                    <a class="link" href="../../reference/has_complement.html" title="has_complement"><code class="computeroutput"><span class="identifier">has_complement</span></code></a>
275                  </p>
276                </td>
277</tr>
278<tr>
279<td>
280                  <p>
281                    <code class="computeroutput"><span class="special">*</span></code>
282                  </p>
283                </td>
284<td>
285                  <p>
286                    <a class="link" href="../../reference/has_dereference.html" title="has_dereference"><code class="computeroutput"><span class="identifier">has_dereference</span></code></a>
287                  </p>
288                </td>
289</tr>
290<tr>
291<td>
292                  <p>
293                    <code class="computeroutput"><span class="special">++</span></code>
294                  </p>
295                </td>
296<td>
297                  <p>
298                    <a class="link" href="../../reference/has_pre_increment.html" title="has_pre_increment"><code class="computeroutput"><span class="identifier">has_pre_increment</span></code></a>
299                  </p>
300                </td>
301</tr>
302<tr>
303<td>
304                  <p>
305                    <code class="computeroutput"><span class="special">--</span></code>
306                  </p>
307                </td>
308<td>
309                  <p>
310                    <a class="link" href="../../reference/has_pre_decrement.html" title="has_pre_decrement"><code class="computeroutput"><span class="identifier">has_pre_decrement</span></code></a>
311                  </p>
312                </td>
313</tr>
314</tbody>
315</table></div>
316</div>
317<br class="table-break"><div class="table">
318<a name="boost_typetraits.category.value_traits.operators.supported_postfix_operators"></a><p class="title"><b>Table 1.5. Supported postfix operators</b></p>
319<div class="table-contents"><table class="table" summary="Supported postfix operators">
320<colgroup>
321<col>
322<col>
323</colgroup>
324<thead><tr>
325<th>
326                  <p>
327                    postfix operator
328                  </p>
329                </th>
330<th>
331                  <p>
332                    trait name
333                  </p>
334                </th>
335</tr></thead>
336<tbody>
337<tr>
338<td>
339                  <p>
340                    <code class="computeroutput"><span class="special">++</span></code>
341                  </p>
342                </td>
343<td>
344                  <p>
345                    <a class="link" href="../../reference/has_post_increment.html" title="has_post_increment"><code class="computeroutput"><span class="identifier">has_post_increment</span></code></a>
346                    <code class="computeroutput"><span class="special">&lt;</span> <span class="keyword">class</span>
347                    <span class="identifier">Lhs</span><span class="special">,</span>
348                    <span class="keyword">class</span> <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span>
349                    <span class="special">&gt;</span></code>
350                  </p>
351                </td>
352</tr>
353<tr>
354<td>
355                  <p>
356                    <code class="computeroutput"><span class="special">--</span></code>
357                  </p>
358                </td>
359<td>
360                  <p>
361                    <a class="link" href="../../reference/has_post_decrement.html" title="has_post_decrement"><code class="computeroutput"><span class="identifier">has_post_decrement</span></code></a>
362                  </p>
363                </td>
364</tr>
365</tbody>
366</table></div>
367</div>
368<br class="table-break"><div class="table">
369<a name="boost_typetraits.category.value_traits.operators.supported_binary_operators"></a><p class="title"><b>Table 1.6. Supported binary operators</b></p>
370<div class="table-contents"><table class="table" summary="Supported binary operators">
371<colgroup>
372<col>
373<col>
374</colgroup>
375<thead><tr>
376<th>
377                  <p>
378                    binary operator
379                  </p>
380                </th>
381<th>
382                  <p>
383                    trait name
384                  </p>
385                </th>
386</tr></thead>
387<tbody>
388<tr>
389<td>
390                  <p>
391                    <code class="computeroutput"><span class="special">+</span></code>
392                  </p>
393                </td>
394<td>
395                  <p>
396                    <a class="link" href="../../reference/has_plus.html" title="has_plus"><code class="computeroutput"><span class="identifier">has_plus</span></code></a> <code class="computeroutput"><span class="special">&lt;</span> <span class="keyword">class</span>
397                    <span class="identifier">Lhs</span><span class="special">,</span>
398                    <span class="keyword">class</span> <span class="identifier">Rhs</span><span class="special">=</span><span class="identifier">Lhs</span><span class="special">,</span> <span class="keyword">class</span>
399                    <span class="identifier">Ret</span><span class="special">=</span><span class="identifier">dont_care</span> <span class="special">&gt;</span></code>
400                  </p>
401                </td>
402</tr>
403<tr>
404<td>
405                  <p>
406                    <code class="computeroutput"><span class="special">-</span></code>
407                  </p>
408                </td>
409<td>
410                  <p>
411                    <a class="link" href="../../reference/has_minus.html" title="has_minus"><code class="computeroutput"><span class="identifier">has_minus</span></code></a>
412                  </p>
413                </td>
414</tr>
415<tr>
416<td>
417                  <p>
418                    <code class="computeroutput"><span class="special">*</span></code>
419                  </p>
420                </td>
421<td>
422                  <p>
423                    <a class="link" href="../../reference/has_multiplies.html" title="has_multiplies"><code class="computeroutput"><span class="identifier">has_multiplies</span></code></a>
424                  </p>
425                </td>
426</tr>
427<tr>
428<td>
429                  <p>
430                    <code class="computeroutput"><span class="special">/</span></code>
431                  </p>
432                </td>
433<td>
434                  <p>
435                    <a class="link" href="../../reference/has_divides.html" title="has_divides"><code class="computeroutput"><span class="identifier">has_divides</span></code></a>
436                  </p>
437                </td>
438</tr>
439<tr>
440<td>
441                  <p>
442                    <code class="computeroutput"><span class="special">%</span></code>
443                  </p>
444                </td>
445<td>
446                  <p>
447                    <a class="link" href="../../reference/has_modulus.html" title="has_modulus"><code class="computeroutput"><span class="identifier">has_modulus</span></code></a>
448                  </p>
449                </td>
450</tr>
451<tr>
452<td>
453                  <p>
454                    <code class="computeroutput"><span class="special">+=</span></code>
455                  </p>
456                </td>
457<td>
458                  <p>
459                    <a class="link" href="../../reference/has_plus_assign.html" title="has_plus_assign"><code class="computeroutput"><span class="identifier">has_plus_assign</span></code></a>
460                  </p>
461                </td>
462</tr>
463<tr>
464<td>
465                  <p>
466                    <code class="computeroutput"><span class="special">-=</span></code>
467                  </p>
468                </td>
469<td>
470                  <p>
471                    <a class="link" href="../../reference/has_minus_assign.html" title="has_minus_assign"><code class="computeroutput"><span class="identifier">has_minus_assign</span></code></a>
472                  </p>
473                </td>
474</tr>
475<tr>
476<td>
477                  <p>
478                    <code class="computeroutput"><span class="special">*=</span></code>
479                  </p>
480                </td>
481<td>
482                  <p>
483                    <a class="link" href="../../reference/has_multiplies_assign.html" title="has_multiplies_assign"><code class="computeroutput"><span class="identifier">has_multiplies_assign</span></code></a>
484                  </p>
485                </td>
486</tr>
487<tr>
488<td>
489                  <p>
490                    <code class="computeroutput"><span class="special">/=</span></code>
491                  </p>
492                </td>
493<td>
494                  <p>
495                    <a class="link" href="../../reference/has_divides_assign.html" title="has_divides_assign"><code class="computeroutput"><span class="identifier">has_divides_assign</span></code></a>
496                  </p>
497                </td>
498</tr>
499<tr>
500<td>
501                  <p>
502                    <code class="computeroutput"><span class="special">%=</span></code>
503                  </p>
504                </td>
505<td>
506                  <p>
507                    <a class="link" href="../../reference/has_modulus_assign.html" title="has_modulus_assign"><code class="computeroutput"><span class="identifier">has_modulus_assign</span></code></a>
508                  </p>
509                </td>
510</tr>
511<tr>
512<td>
513                  <p>
514                    <code class="computeroutput"><span class="special">&amp;</span></code>
515                  </p>
516                </td>
517<td>
518                  <p>
519                    <a class="link" href="../../reference/has_bit_and.html" title="has_bit_and"><code class="computeroutput"><span class="identifier">has_bit_and</span></code></a>
520                  </p>
521                </td>
522</tr>
523<tr>
524<td>
525                  <p>
526                    <code class="computeroutput"><span class="special">|</span></code>
527                  </p>
528                </td>
529<td>
530                  <p>
531                    <a class="link" href="../../reference/has_bit_or.html" title="has_bit_or"><code class="computeroutput"><span class="identifier">has_bit_or</span></code></a>
532                  </p>
533                </td>
534</tr>
535<tr>
536<td>
537                  <p>
538                    <code class="computeroutput"><span class="special">^</span></code>
539                  </p>
540                </td>
541<td>
542                  <p>
543                    <a class="link" href="../../reference/has_bit_xor.html" title="has_bit_xor"><code class="computeroutput"><span class="identifier">has_bit_xor</span></code></a>
544                  </p>
545                </td>
546</tr>
547<tr>
548<td>
549                  <p>
550                    <code class="computeroutput"><span class="special">&amp;=</span></code>
551                  </p>
552                </td>
553<td>
554                  <p>
555                    <a class="link" href="../../reference/has_bit_and_assign.html" title="has_bit_and_assign"><code class="computeroutput"><span class="identifier">has_bit_and_assign</span></code></a>
556                  </p>
557                </td>
558</tr>
559<tr>
560<td>
561                  <p>
562                    <code class="computeroutput"><span class="special">|=</span></code>
563                  </p>
564                </td>
565<td>
566                  <p>
567                    <a class="link" href="../../reference/has_bit_or_assign.html" title="has_bit_or_assign"><code class="computeroutput"><span class="identifier">has_bit_or_assign</span></code></a>
568                  </p>
569                </td>
570</tr>
571<tr>
572<td>
573                  <p>
574                    <code class="computeroutput"><span class="special">^=</span></code>
575                  </p>
576                </td>
577<td>
578                  <p>
579                    <a class="link" href="../../reference/has_bit_xor_assign.html" title="has_bit_xor_assign"><code class="computeroutput"><span class="identifier">has_bit_xor_assign</span></code></a>
580                  </p>
581                </td>
582</tr>
583<tr>
584<td>
585                  <p>
586                    <code class="computeroutput"><span class="special">&lt;&lt;</span></code>
587                  </p>
588                </td>
589<td>
590                  <p>
591                    <a class="link" href="../../reference/has_left_shift.html" title="has_left_shift"><code class="computeroutput"><span class="identifier">has_left_shift</span></code></a>
592                  </p>
593                </td>
594</tr>
595<tr>
596<td>
597                  <p>
598                    <code class="computeroutput"><span class="special">&gt;&gt;</span></code>
599                  </p>
600                </td>
601<td>
602                  <p>
603                    <a class="link" href="../../reference/has_right_shift.html" title="has_right_shift"><code class="computeroutput"><span class="identifier">has_right_shift</span></code></a>
604                  </p>
605                </td>
606</tr>
607<tr>
608<td>
609                  <p>
610                    <code class="computeroutput"><span class="special">&lt;&lt;=</span></code>
611                  </p>
612                </td>
613<td>
614                  <p>
615                    <a class="link" href="../../reference/has_left_shift_assign.html" title="has_left_shift_assign"><code class="computeroutput"><span class="identifier">has_left_shift_assign</span></code></a>
616                  </p>
617                </td>
618</tr>
619<tr>
620<td>
621                  <p>
622                    <code class="computeroutput"><span class="special">&gt;&gt;=</span></code>
623                  </p>
624                </td>
625<td>
626                  <p>
627                    <a class="link" href="../../reference/has_right_shift_assign.html" title="has_right_shift_assign"><code class="computeroutput"><span class="identifier">has_right_shift_assign</span></code></a>
628                  </p>
629                </td>
630</tr>
631<tr>
632<td>
633                  <p>
634                    <code class="computeroutput"><span class="special">==</span></code>
635                  </p>
636                </td>
637<td>
638                  <p>
639                    <a class="link" href="../../reference/has_equal_to.html" title="has_equal_to"><code class="computeroutput"><span class="identifier">has_equal_to</span></code></a>
640                  </p>
641                </td>
642</tr>
643<tr>
644<td>
645                  <p>
646                    <code class="computeroutput"><span class="special">!=</span></code>
647                  </p>
648                </td>
649<td>
650                  <p>
651                    <a class="link" href="../../reference/has_not_equal_to.html" title="has_not_equal_to"><code class="computeroutput"><span class="identifier">has_not_equal_to</span></code></a>
652                  </p>
653                </td>
654</tr>
655<tr>
656<td>
657                  <p>
658                    <code class="computeroutput"><span class="special">&lt;</span></code>
659                  </p>
660                </td>
661<td>
662                  <p>
663                    <a class="link" href="../../reference/has_less.html" title="has_less"><code class="computeroutput"><span class="identifier">has_less</span></code></a>
664                  </p>
665                </td>
666</tr>
667<tr>
668<td>
669                  <p>
670                    <code class="computeroutput"><span class="special">&lt;=</span></code>
671                  </p>
672                </td>
673<td>
674                  <p>
675                    <a class="link" href="../../reference/has_less_equal.html" title="has_less_equal"><code class="computeroutput"><span class="identifier">has_less_equal</span></code></a>
676                  </p>
677                </td>
678</tr>
679<tr>
680<td>
681                  <p>
682                    <code class="computeroutput"><span class="special">&gt;</span></code>
683                  </p>
684                </td>
685<td>
686                  <p>
687                    <a class="link" href="../../reference/has_greater.html" title="has_greater"><code class="computeroutput"><span class="identifier">has_greater</span></code></a>
688                  </p>
689                </td>
690</tr>
691<tr>
692<td>
693                  <p>
694                    <code class="computeroutput"><span class="special">&gt;=</span></code>
695                  </p>
696                </td>
697<td>
698                  <p>
699                    <a class="link" href="../../reference/has_greater_equal.html" title="has_greater_equal"><code class="computeroutput"><span class="identifier">has_greater_equal</span></code></a>
700                  </p>
701                </td>
702</tr>
703<tr>
704<td>
705                  <p>
706                    <code class="computeroutput"><span class="special">&amp;&amp;</span></code>
707                  </p>
708                </td>
709<td>
710                  <p>
711                    <a class="link" href="../../reference/has_logical_and.html" title="has_logical_and"><code class="computeroutput"><span class="identifier">has_logical_and</span></code></a>
712                  </p>
713                </td>
714</tr>
715<tr>
716<td>
717                  <p>
718                    <code class="computeroutput"><span class="special">||</span></code>
719                  </p>
720                </td>
721<td>
722                  <p>
723                    <a class="link" href="../../reference/has_logical_or.html" title="has_logical_or"><code class="computeroutput"><span class="identifier">has_logical_or</span></code></a>
724                  </p>
725                </td>
726</tr>
727</tbody>
728</table></div>
729</div>
730<br class="table-break"><p>
731          The following operators are not supported because they could not be implemented
732          using the same technique: <code class="computeroutput"><span class="keyword">operator</span><span class="special">=</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">-&gt;</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">&amp;</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">,</span></code>, <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">operator</span>
733          <span class="keyword">new</span></code>.
734        </p>
735<h6>
736<a name="boost_typetraits.category.value_traits.operators.h3"></a>
737          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.cv_qualifiers_and_references"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.cv_qualifiers_and_references">cv
738          qualifiers and references</a>
739        </h6>
740<p>
741          A reference sign <code class="computeroutput"><span class="special">&amp;</span></code> in
742          the operator argument is ignored so that <code class="computeroutput"><span class="identifier">has_plus</span><span class="special">&lt;</span> <span class="keyword">int</span><span class="special">&amp;,</span> <span class="keyword">double</span><span class="special">&amp;</span> <span class="special">&gt;::</span><span class="identifier">value</span><span class="special">==</span><span class="identifier">has_plus</span><span class="special">&lt;</span>
743          <span class="keyword">int</span><span class="special">,</span> <span class="keyword">double</span> <span class="special">&gt;::</span><span class="identifier">value</span></code>. This has been chosen because if
744          the following code works (does not work):
745</p>
746<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
747<span class="keyword">double</span> <span class="identifier">d</span><span class="special">;</span>
748<span class="identifier">i</span><span class="special">+</span><span class="identifier">d</span><span class="special">;</span>
749</pre>
750<p>
751          the following code also works (does not work):
752</p>
753<pre class="programlisting"><span class="keyword">int</span> <span class="special">&amp;</span><span class="identifier">ir</span><span class="special">=</span><span class="identifier">i</span><span class="special">;</span>
754<span class="keyword">double</span> <span class="special">&amp;</span><span class="identifier">dr</span><span class="special">=</span><span class="identifier">d</span><span class="special">;</span>
755<span class="identifier">ir</span><span class="special">+</span><span class="identifier">dr</span><span class="special">;</span>
756</pre>
757<p>
758        </p>
759<p>
760          It was not possible to handle properly the <code class="computeroutput"><span class="keyword">volatile</span></code>
761          qualifier so that any construct using this qualifier has undefined behavior.
762        </p>
763<p>
764          As a help, the following tables give the necessary conditions over each
765          trait template argument for the trait <code class="computeroutput"><span class="identifier">value</span></code>
766          to be <code class="computeroutput"><span class="keyword">true</span></code>. They are non sufficient
767          conditions because the conditions must be <code class="computeroutput"><span class="keyword">true</span></code>
768          for all arguments and return type for <code class="computeroutput"><span class="identifier">value</span></code>
769          to be <code class="computeroutput"><span class="keyword">true</span></code>.
770        </p>
771<div class="table">
772<a name="boost_typetraits.category.value_traits.operators.necessary_and_non_sufficient_condition_on_operator_argument_for_value_to_be_true"></a><p class="title"><b>Table 1.7. necessary and non sufficient condition on operator argument for
773          value to be true</b></p>
774<div class="table-contents"><table class="table" summary="necessary and non sufficient condition on operator argument for
775          value to be true">
776<colgroup>
777<col>
778<col>
779<col>
780<col>
781</colgroup>
782<thead><tr>
783<th>
784                  <p>
785                    operator declaration
786                  </p>
787                </th>
788<th>
789                  <p>
790                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
791                    <span class="keyword">void</span> <span class="special">&gt;</span></code>
792                  </p>
793                </th>
794<th>
795                  <p>
796                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
797                    <span class="identifier">Arg</span> <span class="special">&gt;</span></code>
798                    and <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
799                    <span class="identifier">Arg</span><span class="special">&amp;</span>
800                    <span class="special">&gt;</span></code>
801                  </p>
802                </th>
803<th>
804                  <p>
805                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
806                    <span class="identifier">Arg</span> <span class="keyword">const</span>
807                    <span class="special">&gt;</span></code> and <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
808                    <span class="identifier">Arg</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">&gt;</span></code>
809                  </p>
810                </th>
811</tr></thead>
812<tbody>
813<tr>
814<td>
815                  <p>
816                    <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span><span class="special">)</span></code>
817                  </p>
818                </td>
819<td>
820                  <p>
821                    false
822                  </p>
823                </td>
824<td>
825                  <p>
826                    true
827                  </p>
828                </td>
829<td>
830                  <p>
831                    true
832                  </p>
833                </td>
834</tr>
835<tr>
836<td>
837                  <p>
838                    <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span>
839                    <span class="keyword">const</span><span class="special">)</span></code>
840                  </p>
841                </td>
842<td>
843                  <p>
844                    false
845                  </p>
846                </td>
847<td>
848                  <p>
849                    true
850                  </p>
851                </td>
852<td>
853                  <p>
854                    true
855                  </p>
856                </td>
857</tr>
858<tr>
859<td>
860                  <p>
861                    <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span>
862                    <span class="special">&amp;)</span></code>
863                  </p>
864                </td>
865<td>
866                  <p>
867                    false
868                  </p>
869                </td>
870<td>
871                  <p>
872                    true
873                  </p>
874                </td>
875<td>
876                  <p>
877                    false
878                  </p>
879                </td>
880</tr>
881<tr>
882<td>
883                  <p>
884                    <code class="computeroutput"><span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(</span><span class="identifier">Arg</span>
885                    <span class="keyword">const</span> <span class="special">&amp;)</span></code>
886                  </p>
887                </td>
888<td>
889                  <p>
890                    false
891                  </p>
892                </td>
893<td>
894                  <p>
895                    true
896                  </p>
897                </td>
898<td>
899                  <p>
900                    true
901                  </p>
902                </td>
903</tr>
904</tbody>
905</table></div>
906</div>
907<br class="table-break"><div class="table">
908<a name="boost_typetraits.category.value_traits.operators.necessary_and_non_sufficient_condition_on_operator_return_type_for_value_to_be_true"></a><p class="title"><b>Table 1.8. necessary and non sufficient condition on operator return type for
909          value to be true</b></p>
910<div class="table-contents"><table class="table" summary="necessary and non sufficient condition on operator return type for
911          value to be true">
912<colgroup>
913<col>
914<col>
915<col>
916<col>
917<col>
918<col>
919</colgroup>
920<thead><tr>
921<th>
922                  <p>
923                    operator declaration
924                  </p>
925                </th>
926<th>
927                  <p>
928                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
929                    <span class="special">...,</span> <span class="keyword">void</span>
930                    <span class="special">&gt;</span></code>
931                  </p>
932                </th>
933<th>
934                  <p>
935                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
936                    <span class="special">...,</span> <span class="identifier">Ret</span>
937                    <span class="special">&gt;</span></code>
938                  </p>
939                </th>
940<th>
941                  <p>
942                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
943                    <span class="special">...,</span> <span class="identifier">Ret</span>
944                    <span class="keyword">const</span> <span class="special">&gt;</span></code>
945                  </p>
946                </th>
947<th>
948                  <p>
949                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
950                    <span class="special">...,</span> <span class="identifier">Ret</span>
951                    <span class="special">&amp;</span> <span class="special">&gt;</span></code>
952                  </p>
953                </th>
954<th>
955                  <p>
956                    <code class="computeroutput"><span class="identifier">has_op</span><span class="special">&lt;</span>
957                    <span class="special">...,</span> <span class="identifier">Ret</span>
958                    <span class="keyword">const</span> <span class="special">&amp;</span>
959                    <span class="special">&gt;</span></code>
960                  </p>
961                </th>
962</tr></thead>
963<tbody>
964<tr>
965<td>
966                  <p>
967                    <code class="computeroutput"><span class="keyword">void</span> <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code>
968                  </p>
969                </td>
970<td>
971                  <p>
972                    true
973                  </p>
974                </td>
975<td>
976                  <p>
977                    false
978                  </p>
979                </td>
980<td>
981                  <p>
982                    false
983                  </p>
984                </td>
985<td>
986                  <p>
987                    false
988                  </p>
989                </td>
990<td>
991                  <p>
992                    false
993                  </p>
994                </td>
995</tr>
996<tr>
997<td>
998                  <p>
999                    <code class="computeroutput"><span class="identifier">Ret</span> <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code>
1000                  </p>
1001                </td>
1002<td>
1003                  <p>
1004                    false
1005                  </p>
1006                </td>
1007<td>
1008                  <p>
1009                    true
1010                  </p>
1011                </td>
1012<td>
1013                  <p>
1014                    true
1015                  </p>
1016                </td>
1017<td>
1018                  <p>
1019                    false
1020                  </p>
1021                </td>
1022<td>
1023                  <p>
1024                    true
1025                  </p>
1026                </td>
1027</tr>
1028<tr>
1029<td>
1030                  <p>
1031                    <code class="computeroutput"><span class="identifier">Ret</span> <span class="keyword">const</span>
1032                    <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code>
1033                  </p>
1034                </td>
1035<td>
1036                  <p>
1037                    false
1038                  </p>
1039                </td>
1040<td>
1041                  <p>
1042                    true
1043                  </p>
1044                </td>
1045<td>
1046                  <p>
1047                    true
1048                  </p>
1049                </td>
1050<td>
1051                  <p>
1052                    false
1053                  </p>
1054                </td>
1055<td>
1056                  <p>
1057                    true
1058                  </p>
1059                </td>
1060</tr>
1061<tr>
1062<td>
1063                  <p>
1064                    <code class="computeroutput"><span class="identifier">Ret</span> <span class="special">&amp;</span>
1065                    <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code>
1066                  </p>
1067                </td>
1068<td>
1069                  <p>
1070                    false
1071                  </p>
1072                </td>
1073<td>
1074                  <p>
1075                    true
1076                  </p>
1077                </td>
1078<td>
1079                  <p>
1080                    true
1081                  </p>
1082                </td>
1083<td>
1084                  <p>
1085                    true
1086                  </p>
1087                </td>
1088<td>
1089                  <p>
1090                    true
1091                  </p>
1092                </td>
1093</tr>
1094<tr>
1095<td>
1096                  <p>
1097                    <code class="computeroutput"><span class="identifier">Ret</span> <span class="keyword">const</span>
1098                    <span class="special">&amp;</span> <span class="keyword">operator</span></code>@<code class="computeroutput"><span class="special">(...)</span></code>
1099                  </p>
1100                </td>
1101<td>
1102                  <p>
1103                    false
1104                  </p>
1105                </td>
1106<td>
1107                  <p>
1108                    true
1109                  </p>
1110                </td>
1111<td>
1112                  <p>
1113                    true
1114                  </p>
1115                </td>
1116<td>
1117                  <p>
1118                    false
1119                  </p>
1120                </td>
1121<td>
1122                  <p>
1123                    true
1124                  </p>
1125                </td>
1126</tr>
1127</tbody>
1128</table></div>
1129</div>
1130<br class="table-break"><h6>
1131<a name="boost_typetraits.category.value_traits.operators.h4"></a>
1132          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.implementation"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.implementation">Implementation</a>
1133        </h6>
1134<p>
1135          The implementation consists in only header files. The following headers
1136          should included first:
1137</p>
1138<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_operator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></pre>
1139<p>
1140          or
1141</p>
1142<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_op</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></pre>
1143<p>
1144          where <code class="literal">op</code> is the textual name chosen for the wanted operator.
1145          The first method includes all operator traits.
1146        </p>
1147<p>
1148          All traits are implemented the same way using preprocessor macros to avoid
1149          code duplication. The main files are in <code class="literal">boost/type_traits/detail</code>:
1150          <code class="literal">has_binary_operator.hpp</code>, <code class="literal">has_prefix_operator.hpp</code>
1151          and <code class="literal">has_postfix_operator.hpp</code>. The example of prefix
1152          <code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code>
1153          is presented below:
1154        </p>
1155<p>
1156</p>
1157<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
1158<span class="keyword">namespace</span> <span class="identifier">detail</span> <span class="special">{</span>
1159
1160<span class="comment">// This namespace ensures that argument-dependent name lookup does not mess things up.</span>
1161<span class="keyword">namespace</span> <span class="identifier">has_unary_minus_impl</span> <span class="special">{</span>
1162
1163<span class="comment">// 1. a function to have an instance of type T without requiring T to be default</span>
1164<span class="comment">// constructible</span>
1165<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="special">&amp;</span><span class="identifier">make</span><span class="special">();</span>
1166
1167
1168<span class="comment">// 2. we provide our operator definition for types that do not have one already</span>
1169
1170<span class="comment">// a type returned from operator- when no such operator is</span>
1171<span class="comment">// found in the type's own namespace (our own operator is used) so that we have</span>
1172<span class="comment">// a means to know that our operator was used</span>
1173<span class="keyword">struct</span> <span class="identifier">no_operator</span> <span class="special">{</span> <span class="special">};</span>
1174
1175<span class="comment">// this class allows implicit conversions and makes the following operator</span>
1176<span class="comment">// definition less-preferred than any other such operators that might be found</span>
1177<span class="comment">// via argument-dependent name lookup</span>
1178<span class="keyword">struct</span> <span class="identifier">any</span> <span class="special">{</span> <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">any</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="special">};</span>
1179
1180<span class="comment">// when operator- is not available, this one is used</span>
1181<span class="identifier">no_operator</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">any</span><span class="special">&amp;);</span>
1182
1183
1184<span class="comment">// 3. checks if the operator returns void or not</span>
1185<span class="comment">// conditions: Rhs!=void</span>
1186
1187<span class="comment">// we first redefine "operator," so that we have no compilation error if</span>
1188<span class="comment">// operator- returns void and we can use the return type of</span>
1189<span class="comment">// (-rhs, returns_void_t()) to deduce if operator- returns void or not:</span>
1190<span class="comment">// - operator- returns void   -&gt; (-rhs, returns_void_t()) returns returns_void_t</span>
1191<span class="comment">// - operator- returns !=void -&gt; (-rhs, returns_void_t()) returns int</span>
1192<span class="keyword">struct</span> <span class="identifier">returns_void_t</span> <span class="special">{</span> <span class="special">};</span>
1193<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">,(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&amp;,</span> <span class="identifier">returns_void_t</span><span class="special">);</span>
1194<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">,(</span><span class="keyword">const</span> <span class="keyword">volatile</span> <span class="identifier">T</span><span class="special">&amp;,</span> <span class="identifier">returns_void_t</span><span class="special">);</span>
1195
1196<span class="comment">// this intermediate trait has member value of type bool:</span>
1197<span class="comment">// - value==true  -&gt; operator- returns void</span>
1198<span class="comment">// - value==false -&gt; operator- does not return void</span>
1199<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">&gt;</span>
1200<span class="keyword">struct</span> <span class="identifier">operator_returns_void</span> <span class="special">{</span>
1201   <span class="comment">// overloads of function returns_void make the difference</span>
1202   <span class="comment">// yes_type and no_type have different size by construction</span>
1203   <span class="keyword">static</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">yes_type</span> <span class="identifier">returns_void</span><span class="special">(</span><span class="identifier">returns_void_t</span><span class="special">);</span>
1204   <span class="keyword">static</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">no_type</span> <span class="identifier">returns_void</span><span class="special">(</span><span class="keyword">int</span><span class="special">);</span>
1205   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">yes_type</span><span class="special">)==</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">returns_void</span><span class="special">((-</span><span class="identifier">make</span><span class="special">&lt;</span><span class="identifier">Rhs</span><span class="special">&gt;(),</span><span class="identifier">returns_void_t</span><span class="special">())));</span>
1206<span class="special">};</span>
1207
1208
1209<span class="comment">// 4. checks if the return type is Ret or Ret==dont_care</span>
1210<span class="comment">// conditions: Rhs!=void</span>
1211
1212<span class="keyword">struct</span> <span class="identifier">dont_care</span> <span class="special">{</span> <span class="special">};</span>
1213
1214<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">Returns_void</span> <span class="special">&gt;</span>
1215<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span><span class="special">;</span>
1216
1217<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">&gt;</span>
1218<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">dont_care</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">&gt;</span> <span class="special">{</span>
1219   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
1220<span class="special">};</span>
1221
1222<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">&gt;</span>
1223<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">dont_care</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">&gt;</span> <span class="special">{</span>
1224   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
1225<span class="special">};</span>
1226
1227<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">&gt;</span>
1228<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">&gt;</span> <span class="special">{</span>
1229   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
1230<span class="special">};</span>
1231
1232<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">&gt;</span>
1233<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">&gt;</span> <span class="special">{</span>
1234   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
1235<span class="special">};</span>
1236
1237<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">&gt;</span>
1238<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">&gt;</span> <span class="special">{</span>
1239   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
1240<span class="special">};</span>
1241
1242<span class="comment">// otherwise checks if it is convertible to Ret using the sizeof trick</span>
1243<span class="comment">// based on overload resolution</span>
1244<span class="comment">// condition: Ret!=void and Ret!=dont_care and the operator does not return void</span>
1245<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">&gt;</span>
1246<span class="keyword">struct</span> <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">&gt;</span> <span class="special">{</span>
1247   <span class="keyword">static</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">yes_type</span> <span class="identifier">is_convertible_to_Ret</span><span class="special">(</span><span class="identifier">Ret</span><span class="special">);</span> <span class="comment">// this version is preferred for types convertible to Ret</span>
1248   <span class="keyword">static</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">no_type</span> <span class="identifier">is_convertible_to_Ret</span><span class="special">(...);</span> <span class="comment">// this version is used otherwise</span>
1249
1250   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">is_convertible_to_Ret</span><span class="special">(-</span><span class="identifier">make</span><span class="special">&lt;</span><span class="identifier">Rhs</span><span class="special">&gt;()))==</span><span class="keyword">sizeof</span><span class="special">(::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">yes_type</span><span class="special">);</span>
1251<span class="special">};</span>
1252
1253
1254<span class="comment">// 5. checks for operator existence</span>
1255<span class="comment">// condition: Rhs!=void</span>
1256
1257<span class="comment">// checks if our definition of operator- is used or an other</span>
1258<span class="comment">// existing one;</span>
1259<span class="comment">// this is done with redefinition of "operator," that returns no_operator or has_operator</span>
1260<span class="keyword">struct</span> <span class="identifier">has_operator</span> <span class="special">{</span> <span class="special">};</span>
1261<span class="identifier">no_operator</span> <span class="keyword">operator</span><span class="special">,(</span><span class="identifier">no_operator</span><span class="special">,</span> <span class="identifier">has_operator</span><span class="special">);</span>
1262
1263<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span> <span class="special">&gt;</span>
1264<span class="keyword">struct</span> <span class="identifier">operator_exists</span> <span class="special">{</span>
1265   <span class="keyword">static</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">yes_type</span> <span class="identifier">check</span><span class="special">(</span><span class="identifier">has_operator</span><span class="special">);</span> <span class="comment">// this version is preferred when operator exists</span>
1266   <span class="keyword">static</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">no_type</span> <span class="identifier">check</span><span class="special">(</span><span class="identifier">no_operator</span><span class="special">);</span> <span class="comment">// this version is used otherwise</span>
1267
1268   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">check</span><span class="special">(((-</span><span class="identifier">make</span><span class="special">&lt;</span><span class="identifier">Rhs</span><span class="special">&gt;()),</span><span class="identifier">make</span><span class="special">&lt;</span><span class="identifier">has_operator</span><span class="special">&gt;())))==</span><span class="keyword">sizeof</span><span class="special">(::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">yes_type</span><span class="special">);</span>
1269<span class="special">};</span>
1270
1271
1272<span class="comment">// 6. main trait: to avoid any compilation error, this class behaves</span>
1273<span class="comment">// differently when operator-(Rhs) is forbidden by the standard.</span>
1274<span class="comment">// Forbidden_if is a bool that is:</span>
1275<span class="comment">// - true when the operator-(Rhs) is forbidden by the standard</span>
1276<span class="comment">//   (would yield compilation error if used)</span>
1277<span class="comment">// - false otherwise</span>
1278<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">Forbidden_if</span> <span class="special">&gt;</span>
1279<span class="keyword">struct</span> <span class="identifier">trait_impl1</span><span class="special">;</span>
1280
1281<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">&gt;</span>
1282<span class="keyword">struct</span> <span class="identifier">trait_impl1</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">true</span> <span class="special">&gt;</span> <span class="special">{</span>
1283   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
1284<span class="special">};</span>
1285
1286<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">&gt;</span>
1287<span class="keyword">struct</span> <span class="identifier">trait_impl1</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">&gt;</span> <span class="special">{</span>
1288   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span>
1289      <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">type_traits</span><span class="special">::</span><span class="identifier">ice_and</span><span class="special">&lt;</span>
1290         <span class="identifier">operator_exists</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span> <span class="special">&gt;::</span><span class="identifier">value</span><span class="special">,</span>
1291         <span class="identifier">operator_returns_Ret</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="identifier">operator_returns_void</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span> <span class="special">&gt;::</span><span class="identifier">value</span> <span class="special">&gt;::</span><span class="identifier">value</span>
1292      <span class="special">&gt;::</span><span class="identifier">value</span>
1293   <span class="special">;</span>
1294<span class="special">};</span>
1295
1296<span class="comment">// specialization needs to be declared for the special void case</span>
1297<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">&gt;</span>
1298<span class="keyword">struct</span> <span class="identifier">trait_impl1</span> <span class="special">&lt;</span> <span class="keyword">void</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="keyword">false</span> <span class="special">&gt;</span> <span class="special">{</span>
1299   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
1300<span class="special">};</span>
1301
1302<span class="comment">// defines some typedef for convenience</span>
1303<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span> <span class="special">&gt;</span>
1304<span class="keyword">struct</span> <span class="identifier">trait_impl</span> <span class="special">{</span>
1305   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span><span class="identifier">Rhs</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">Rhs_noref</span><span class="special">;</span>
1306   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_cv</span><span class="special">&lt;</span><span class="identifier">Rhs_noref</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">Rhs_nocv</span><span class="special">;</span>
1307   <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_cv</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_pointer</span><span class="special">&lt;</span><span class="identifier">Rhs_noref</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">Rhs_noptr</span><span class="special">;</span>
1308   <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">bool</span> <span class="identifier">value</span> <span class="special">=</span> <span class="identifier">trait_impl1</span> <span class="special">&lt;</span> <span class="identifier">Rhs_noref</span><span class="special">,</span> <span class="identifier">Ret</span><span class="special">,</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_pointer</span><span class="special">&lt;</span> <span class="identifier">Rhs_noref</span> <span class="special">&gt;::</span><span class="identifier">value</span> <span class="special">&gt;::</span><span class="identifier">value</span><span class="special">;</span>
1309<span class="special">};</span>
1310
1311<span class="special">}</span> <span class="comment">// namespace impl</span>
1312<span class="special">}</span> <span class="comment">// namespace detail</span>
1313
1314<span class="comment">// this is the accessible definition of the trait to end user</span>
1315<span class="keyword">template</span> <span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Ret</span><span class="special">=::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">has_unary_minus_impl</span><span class="special">::</span><span class="identifier">dont_care</span> <span class="special">&gt;</span>
1316<span class="keyword">struct</span> <span class="identifier">has_unary_minus</span> <span class="special">:</span> <span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">integral_constant</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">,(::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">has_unary_minus_impl</span><span class="special">::</span><span class="identifier">trait_impl</span> <span class="special">&lt;</span> <span class="identifier">Rhs</span><span class="special">,</span> <span class="identifier">Ret</span> <span class="special">&gt;::</span><span class="identifier">value</span><span class="special">)&gt;</span> <span class="special">{</span> <span class="special">};</span>
1317
1318<span class="special">}</span> <span class="comment">// namespace boost</span>
1319</pre>
1320<p>
1321        </p>
1322<h6>
1323<a name="boost_typetraits.category.value_traits.operators.h5"></a>
1324          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.limitation"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.limitation">Limitation</a>
1325        </h6>
1326<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
1327              Requires a compiler with working SFINAE.
1328            </li></ul></div>
1329<h6>
1330<a name="boost_typetraits.category.value_traits.operators.h6"></a>
1331          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.known_issues"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.known_issues">Known
1332          issues</a>
1333        </h6>
1334<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1335<li class="listitem">
1336              These traits cannot detect whether the operators are public or not:
1337              if an operator is defined as a private member of type <code class="computeroutput"><span class="identifier">T</span></code> then the instantiation of the corresponding
1338              trait will produce a compiler error. For this reason these traits cannot
1339              be used to determine whether a type has a public operator or not.
1340<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="keyword">private</span><span class="special">:</span> <span class="identifier">A</span> <span class="keyword">operator</span><span class="special">-();</span> <span class="special">};</span>
1341<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: A::operator-() is private</span>
1342</pre>
1343            </li>
1344<li class="listitem">
1345              There is an issue if the operator exists only for type <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>
1346              is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
1347              In this case, the compiler will report an ambiguous overload because
1348              both the existing operator and the one we provide (with argument of
1349              type <code class="computeroutput"><span class="identifier">any</span></code>) need type
1350              conversion, so that none is preferred.
1351<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
1352<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&amp;);</span>
1353<span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="keyword">operator</span> <span class="identifier">A</span><span class="special">();</span> <span class="special">};</span>
1354<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
1355<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special">&lt;</span><span class="identifier">B</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload between</span>
1356                                  <span class="comment">// operator-(const any&amp;) and</span>
1357                                  <span class="comment">// operator-(const A&amp;)</span>
1358                                  <span class="comment">// both need type conversion</span>
1359</pre>
1360<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">B</span> <span class="special">{</span> <span class="special">};</span>
1361<span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="identifier">A</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">B</span><span class="special">&amp;)</span> <span class="special">{</span> <span class="special">}</span> <span class="special">};</span>
1362<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">-(</span><span class="keyword">const</span> <span class="identifier">A</span><span class="special">&amp;);</span>
1363<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special">&lt;</span><span class="identifier">A</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// this is fine</span>
1364<span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_unary_minus</span><span class="special">&lt;</span><span class="identifier">B</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">;</span> <span class="comment">// error: ambiguous overload between</span>
1365                                  <span class="comment">// operator-(const any&amp;) and</span>
1366                                  <span class="comment">// operator-(const A&amp;)</span>
1367                                  <span class="comment">// both need type conversion</span>
1368</pre>
1369            </li>
1370<li class="listitem">
1371              There is an issue when applying these traits to template classes. If
1372              the operator is defined but does not bind for a given template type,
1373              it is still detected by the trait which returns <code class="computeroutput"><span class="keyword">true</span></code>
1374              instead of <code class="computeroutput"><span class="keyword">false</span></code>. This
1375              applies in particular to the containers of the standard library and
1376              <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code>.
1377              Example:
1378<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">has_equal_to</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1379<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
1380
1381<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
1382<span class="keyword">struct</span> <span class="identifier">contains</span> <span class="special">{</span> <span class="identifier">T</span> <span class="identifier">data</span><span class="special">;</span> <span class="special">};</span>
1383
1384<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
1385<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">contains</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="identifier">lhs</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">contains</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">{</span>
1386	<span class="keyword">return</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">lhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">data</span><span class="special">);</span>
1387<span class="special">}</span>
1388
1389<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
1390<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
1391<span class="keyword">bool</span> <span class="identifier">f</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">good</span><span class="special">&amp;,</span> <span class="keyword">const</span> <span class="identifier">good</span><span class="special">&amp;)</span> <span class="special">{</span> <span class="special">}</span>
1392
1393<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
1394	<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">boolalpha</span><span class="special">;</span>
1395	<span class="comment">// works fine for contains&lt;good&gt;</span>
1396	<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special">&lt;</span> <span class="identifier">contains</span><span class="special">&lt;</span> <span class="identifier">good</span> <span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">value</span><span class="special">&lt;&lt;</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true</span>
1397	<span class="identifier">contains</span><span class="special">&lt;</span><span class="identifier">good</span><span class="special">&gt;</span> <span class="identifier">g</span><span class="special">;</span>
1398	<span class="identifier">g</span><span class="special">==</span><span class="identifier">g</span><span class="special">;</span> <span class="comment">// ok</span>
1399	<span class="comment">// does not work for contains&lt;bad&gt;</span>
1400	<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">&lt;&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">has_equal_to</span><span class="special">&lt;</span> <span class="identifier">contains</span><span class="special">&lt;</span> <span class="identifier">bad</span> <span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">value</span><span class="special">&lt;&lt;</span><span class="char">'\n'</span><span class="special">;</span> <span class="comment">// true, should be false</span>
1401	<span class="identifier">contains</span><span class="special">&lt;</span><span class="identifier">bad</span><span class="special">&gt;</span> <span class="identifier">b</span><span class="special">;</span>
1402	<span class="identifier">b</span><span class="special">==</span><span class="identifier">b</span><span class="special">;</span> <span class="comment">// compile time error</span>
1403	<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
1404<span class="special">}</span>
1405</pre>
1406            </li>
1407<li class="listitem">
1408              <code class="computeroutput"><span class="keyword">volatile</span></code> qualifier is
1409              not properly handled and would lead to undefined behavior
1410            </li>
1411</ul></div>
1412<h6>
1413<a name="boost_typetraits.category.value_traits.operators.h7"></a>
1414          <span class="phrase"><a name="boost_typetraits.category.value_traits.operators.acknowledgments"></a></span><a class="link" href="operators.html#boost_typetraits.category.value_traits.operators.acknowledgments">Acknowledgments</a>
1415        </h6>
1416<p>
1417          Frederic Bron is very thankful to numerous people from the boost mailing
1418          list for their kind help and patience. In particular, the following persons
1419          have been very helpful for the implementation: Edward Diener, Eric Niebler,
1420          Jeffrey Lee Hellrung (Jr.), Robert Stewart, Roman Perepelitsa, Steven Watanabe,
1421          Vicente Botet.
1422        </p>
1423</div>
1424<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
1425<td align="left"></td>
1426<td align="right"><div class="copyright-footer">Copyright © 2000, 2011 Adobe Systems Inc, David Abrahams,
1427      Frederic Bron, Steve Cleary, Beman Dawes, Glen Fernandes, Aleksey Gurtovoy,
1428      Howard Hinnant, Jesse Jones, Mat Marcus, Itay Maman, John Maddock, Alexander
1429      Nasonov, Thorsten Ottosen, Roman Perepelitsa, Robert Ramey, Jeremy Siek, Robert
1430      Stewart and Steven Watanabe<p>
1431        Distributed under the Boost Software License, Version 1.0. (See accompanying
1432        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
1433      </p>
1434</div></td>
1435</tr></table>
1436<hr>
1437<div class="spirit-nav">
1438<a accesskey="p" href="relate.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../value_traits.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../transform.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
1439</div>
1440</body>
1441</html>
1442