Update operators docs.

Fixes https://github.com/boostorg/type_traits/issues/160.
This commit is contained in:
jzmaddock
2022-11-21 18:24:04 +00:00
parent 6ffc0e5ebd
commit 2370288a79
6 changed files with 34 additions and 21 deletions

View File

@ -1148,7 +1148,15 @@
All traits are implemented the same way using preprocessor macros to avoid
code duplication. The main files are in <code class="literal">boost/type_traits/detail</code>:
<code class="literal">has_binary_operator.hpp</code>, <code class="literal">has_prefix_operator.hpp</code>
and <code class="literal">has_postfix_operator.hpp</code>. The example of prefix
and <code class="literal">has_postfix_operator.hpp</code>.
</p>
<p>
Given a sufficiently conforming C++11 compiler, these traits are implemented
in a rather compact and straightforward way that should always give accurate
answers.
</p>
<p>
In C++03 there is a legacy implementation, by way of example the prefix
<code class="computeroutput"><span class="keyword">operator</span><span class="special">-</span></code>
is presented below:
</p>
@ -1324,7 +1332,7 @@
<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>
</h6>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Requires a compiler with working SFINAE.
Prior to C++11, requires a compiler with working SFINAE.
</li></ul></div>
<h6>
<a name="boost_typetraits.category.value_traits.operators.h6"></a>
@ -1333,21 +1341,22 @@
</h6>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
These traits cannot detect whether the operators are public or not:
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
trait will produce a compiler error. For this reason these traits cannot
be used to determine whether a type has a public operator or not.
Prior to C++11, these traits cannot detect whether the operators are
public or not: 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 trait will produce a compiler error. For this
reason these traits cannot be used to determine whether a type has
a public operator or not.
<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>
<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>
</pre>
</li>
<li class="listitem">
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>
is convertible to <code class="computeroutput"><span class="identifier">A</span></code>.
In this case, the compiler will report an ambiguous overload because
both the existing operator and the one we provide (with argument of
type <code class="computeroutput"><span class="identifier">any</span></code>) need type
conversion, so that none is preferred.
Prior to C++11, 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> is convertible to <code class="computeroutput"><span class="identifier">A</span></code>. In this case, the compiler will
report an ambiguous overload because both the existing operator and
the one we provide (with argument of type <code class="computeroutput"><span class="identifier">any</span></code>)
need type conversion, so that none is preferred.
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">};</span>
<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>
<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>
@ -1388,7 +1397,7 @@
<span class="keyword">class</span> <span class="identifier">bad</span> <span class="special">{</span> <span class="special">};</span>
<span class="keyword">class</span> <span class="identifier">good</span> <span class="special">{</span> <span class="special">};</span>
<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>
<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="keyword">return</span> <span class="keyword">true</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> <span class="special">{</span>
<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>

View File

@ -24,7 +24,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="id1124648"></a>Class Index</h2></div></div></div>
<a name="id1192383"></a>Class Index</h2></div></div></div>
<p><a class="link" href="s11.html#idx_id_0">A</a> <a class="link" href="s11.html#idx_id_2">C</a> <a class="link" href="s11.html#idx_id_3">D</a> <a class="link" href="s11.html#idx_id_4">E</a> <a class="link" href="s11.html#idx_id_5">F</a> <a class="link" href="s11.html#idx_id_6">H</a> <a class="link" href="s11.html#idx_id_7">I</a> <a class="link" href="s11.html#idx_id_8">M</a> <a class="link" href="s11.html#idx_id_9">N</a> <a class="link" href="s11.html#idx_id_10">O</a> <a class="link" href="s11.html#idx_id_11">P</a> <a class="link" href="s11.html#idx_id_12">R</a> <a class="link" href="s11.html#idx_id_13">T</a></p>
<div class="variablelist"><dl class="variablelist">
<dt>

View File

@ -24,7 +24,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="id1128255"></a>Typedef Index</h2></div></div></div>
<a name="id1195400"></a>Typedef Index</h2></div></div></div>
<p><a class="link" href="s12.html#idx_id_21">F</a> <a class="link" href="s12.html#idx_id_28">R</a> <a class="link" href="s12.html#idx_id_29">T</a> <a class="link" href="s12.html#idx_id_31">V</a></p>
<div class="variablelist"><dl class="variablelist">
<dt>

View File

@ -24,7 +24,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="id1128464"></a>Macro Index</h2></div></div></div>
<a name="id1195591"></a>Macro Index</h2></div></div></div>
<p><a class="link" href="s13.html#idx_id_33">B</a></p>
<div class="variablelist"><dl class="variablelist">
<dt>

View File

@ -23,7 +23,7 @@
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="id1130188"></a>Index</h2></div></div></div>
<a name="id1196594"></a>Index</h2></div></div></div>
<p><a class="link" href="s14.html#idx_id_48">A</a> <a class="link" href="s14.html#idx_id_49">B</a> <a class="link" href="s14.html#idx_id_50">C</a> <a class="link" href="s14.html#idx_id_51">D</a> <a class="link" href="s14.html#idx_id_52">E</a> <a class="link" href="s14.html#idx_id_53">F</a> <a class="link" href="s14.html#idx_id_54">H</a> <a class="link" href="s14.html#idx_id_55">I</a> <a class="link" href="s14.html#idx_id_56">M</a> <a class="link" href="s14.html#idx_id_57">N</a> <a class="link" href="s14.html#idx_id_58">O</a> <a class="link" href="s14.html#idx_id_59">P</a> <a class="link" href="s14.html#idx_id_60">R</a> <a class="link" href="s14.html#idx_id_61">T</a> <a class="link" href="s14.html#idx_id_62">U</a> <a class="link" href="s14.html#idx_id_63">V</a></p>
<div class="variablelist"><dl class="variablelist">
<dt>

View File

@ -247,7 +247,11 @@ All traits are implemented the same way using preprocessor macros to avoid code
duplication.
The main files are in [^boost/type_traits/detail]: [^has_binary_operator.hpp],
[^has_prefix_operator.hpp] and [^has_postfix_operator.hpp].
The example of prefix `operator-` is presented below:
Given a sufficiently conforming C++11 compiler, these traits are implemented in a rather
compact and straightforward way that should always give accurate answers.
In C++03 there is a legacy implementation, by way of example the prefix `operator-` is presented below:
``
namespace boost {
@ -416,11 +420,11 @@ struct has_unary_minus : ::boost::integral_constant<bool,(::boost::detail::has_u
[heading Limitation]
* Requires a compiler with working SFINAE.
* Prior to C++11, requires a compiler with working SFINAE.
[heading Known issues]
* These traits cannot detect whether the operators are public or not:
* Prior to C++11, these traits cannot detect whether the operators are public or not:
if an operator is defined as a private member of type `T` then
the instantiation of the corresponding trait will produce a compiler error.
For this reason these traits cannot be used to determine whether a type has a
@ -430,7 +434,7 @@ struct A { private: A operator-(); };
boost::has_unary_minus<A>::value; // error: A::operator-() is private
``
* There is an issue if the operator exists only for type `A` and `B` is
* Prior to C++11, there is an issue if the operator exists only for type `A` and `B` is
convertible to `A`. In this case, the compiler will report an ambiguous overload
because both the existing operator and the one we provide (with argument of type
`any`) need type conversion, so that none is preferred.