| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> |
| <title>enable_if</title> |
| <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css"> |
| <meta name="generator" content="DocBook XSL Stylesheets V1.78.1"> |
| <link rel="home" href="../index.html" title="Chapter 1. Boost.Core"> |
| <link rel="up" href="../index.html" title="Chapter 1. Boost.Core"> |
| <link rel="prev" href="demangle.html" title="demangle"> |
| <link rel="next" href="explicit_operator_bool.html" title="explicit_operator_bool"> |
| </head> |
| <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> |
| <table cellpadding="2" width="100%"><tr> |
| <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td> |
| <td align="center"><a href="../../../../../index.html">Home</a></td> |
| <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td> |
| <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> |
| <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> |
| <td align="center"><a href="../../../../../more/index.htm">More</a></td> |
| </tr></table> |
| <hr> |
| <div class="spirit-nav"> |
| <a accesskey="p" href="demangle.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="explicit_operator_bool.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> |
| <a name="core.enable_if"></a><a class="link" href="enable_if.html" title="enable_if">enable_if</a> |
| </h2></div></div></div> |
| <div class="toc"><dl class="toc"> |
| <dt><span class="section"><a href="enable_if.html#core.enable_if.introduction">Introduction</a></span></dt> |
| <dt><span class="section"><a href="enable_if.html#core.enable_if.the_enable_if_templates">The enable_if |
| templates</a></span></dt> |
| <dt><span class="section"><a href="enable_if.html#core.enable_if.using_enable_if">Using enable_if</a></span></dt> |
| <dt><span class="section"><a href="enable_if.html#core.enable_if.acknowledgements">Acknowledgements</a></span></dt> |
| <dt><span class="section"><a href="enable_if.html#core.enable_if.references">References</a></span></dt> |
| </dl></div> |
| <div class="simplesect"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="idp85676048"></a>Authors</h3></div></div></div> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| Jaakko Järvi |
| </li> |
| <li class="listitem"> |
| Jeremiah Willcock |
| </li> |
| <li class="listitem"> |
| Andrew Lumsdaine |
| </li> |
| </ul></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="core.enable_if.introduction"></a><a class="link" href="enable_if.html#core.enable_if.introduction" title="Introduction">Introduction</a> |
| </h3></div></div></div> |
| <p> |
| The <code class="computeroutput"><span class="identifier">enable_if</span></code> family of templates |
| is a set of tools to allow a function template or a class template specialization |
| to include or exclude itself from a set of matching functions or specializations |
| based on properties of its template arguments. For example, one can define |
| function templates that are only enabled for, and thus only match, an arbitrary |
| set of types defined by a traits class. The <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| templates can also be applied to enable class template specializations. Applications |
| of <code class="computeroutput"><span class="identifier">enable_if</span></code> are discussed |
| in length in <a class="link" href="enable_if.html#REF1">[1]</a> and <a class="link" href="enable_if.html#REF2">[2]</a>. |
| </p> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.introduction.header_boost_core_enable_if_hpp"></a><a class="link" href="enable_if.html#core.enable_if.introduction.header_boost_core_enable_if_hpp" title="Header <boost/core/enable_if.hpp>">Header |
| <boost/core/enable_if.hpp></a> |
| </h4></div></div></div> |
| <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Cond</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">enable_if</span><span class="special">;</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Cond</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">disable_if</span><span class="special">;</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Cond</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">lazy_enable_if</span><span class="special">;</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Cond</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">lazy_disable_if</span><span class="special">;</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span> <span class="identifier">B</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">enable_if_c</span><span class="special">;</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span> <span class="identifier">B</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">disable_if_c</span><span class="special">;</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span> <span class="identifier">B</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">lazy_enable_if_c</span><span class="special">;</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span> <span class="identifier">B</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">lazy_disable_if_c</span><span class="special">;</span> |
| <span class="special">}</span> |
| </pre> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.introduction.background"></a><a class="link" href="enable_if.html#core.enable_if.introduction.background" title="Background">Background</a> |
| </h4></div></div></div> |
| <p> |
| Sensible operation of template function overloading in C++ relies on the |
| <span class="emphasis"><em>SFINAE</em></span> (substitution-failure-is-not-an-error) principle |
| <a class="link" href="enable_if.html#REF3">[3]</a>: if an invalid argument or return type |
| is formed during the instantiation of a function template, the instantiation |
| is removed from the overload resolution set instead of causing a compilation |
| error. The following example, taken from <a class="link" href="enable_if.html#REF1">[1]</a>, |
| demonstrates why this is important: |
| </p> |
| <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">negate</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">-</span><span class="identifier">i</span><span class="special">;</span> <span class="special">}</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">negate</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">F</span><span class="special">&</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">-</span><span class="identifier">f</span><span class="special">();</span> <span class="special">}</span> |
| </pre> |
| <p> |
| Suppose the compiler encounters the call <code class="computeroutput"><span class="identifier">negate</span><span class="special">(</span><span class="number">1</span><span class="special">)</span></code>. |
| The first definition is obviously a better match, but the compiler must |
| nevertheless consider (and instantiate the prototypes) of both definitions |
| to find this out. Instantiating the latter definition with <code class="computeroutput"><span class="identifier">F</span></code> as <code class="computeroutput"><span class="keyword">int</span></code> |
| would result in: |
| </p> |
| <pre class="programlisting"><span class="keyword">int</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">negate</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&);</span> |
| </pre> |
| <p> |
| where the return type is invalid. If this were an error, adding an unrelated |
| function template (that was never called) could break otherwise valid code. |
| Due to the SFINAE principle the above example is not, however, erroneous. |
| The latter definition of <code class="computeroutput"><span class="identifier">negate</span></code> |
| is simply removed from the overload resolution set. |
| </p> |
| <p> |
| The <code class="computeroutput"><span class="identifier">enable_if</span></code> templates |
| are tools for controlled creation of the SFINAE conditions. |
| </p> |
| </div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="core.enable_if.the_enable_if_templates"></a><a class="link" href="enable_if.html#core.enable_if.the_enable_if_templates" title="The enable_if templates">The enable_if |
| templates</a> |
| </h3></div></div></div> |
| <p> |
| The names of the <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| templates have three parts: an optional <code class="computeroutput"><span class="identifier">lazy_</span></code> |
| tag, either <code class="computeroutput"><span class="identifier">enable_if</span></code> or |
| <code class="computeroutput"><span class="identifier">disable_if</span></code>, and an optional |
| <code class="computeroutput"><span class="identifier">_c</span></code> tag. All eight combinations |
| of these parts are supported. The meaning of the <code class="computeroutput"><span class="identifier">lazy_</span></code> |
| tag is described in the section <a class="link" href="enable_if.html#core.enable_if.using_enable_if.enable_if_lazy" title="Lazy enable_if">below</a>. |
| The second part of the name indicates whether a true condition argument should |
| enable or disable the current overload. The third part of the name indicates |
| whether the condition argument is a <code class="computeroutput"><span class="keyword">bool</span></code> |
| value (<code class="computeroutput"><span class="identifier">_c</span></code> suffix), or a type |
| containing a static <code class="computeroutput"><span class="keyword">bool</span></code> constant |
| named <code class="computeroutput"><span class="identifier">value</span></code> (no suffix). |
| The latter version interoperates with Boost.MPL. |
| </p> |
| <p> |
| The definitions of <code class="computeroutput"><span class="identifier">enable_if_c</span></code> |
| and <code class="computeroutput"><span class="identifier">enable_if</span></code> are as follows |
| (we use <code class="computeroutput"><span class="identifier">enable_if</span></code> templates |
| unqualified but they are in the <code class="computeroutput"><span class="identifier">boost</span></code> |
| namespace). |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span> <span class="identifier">B</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> |
| <span class="keyword">struct</span> <span class="identifier">enable_if_c</span> <span class="special">{</span> |
| <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span> |
| <span class="special">};</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">struct</span> <span class="identifier">enable_if_c</span><span class="special"><</span><span class="keyword">false</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="special">{};</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Cond</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> |
| <span class="keyword">struct</span> <span class="identifier">enable_if</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">enable_if_c</span><span class="special"><</span><span class="identifier">Cond</span><span class="special">::</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">T</span><span class="special">></span> <span class="special">{};</span> |
| </pre> |
| <p> |
| An instantiation of the <code class="computeroutput"><span class="identifier">enable_if_c</span></code> |
| template with the parameter <code class="computeroutput"><span class="identifier">B</span></code> |
| as <code class="computeroutput"><span class="keyword">true</span></code> contains a member type |
| <code class="computeroutput"><span class="identifier">type</span></code>, defined to be <code class="computeroutput"><span class="identifier">T</span></code>. If <code class="computeroutput"><span class="identifier">B</span></code> |
| is <code class="computeroutput"><span class="keyword">false</span></code>, no such member is |
| defined. Thus <code class="computeroutput"><span class="identifier">enable_if_c</span><span class="special"><</span><span class="identifier">B</span><span class="special">,</span> |
| <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span></code> is either a valid or an invalid type |
| expression, depending on the value of <code class="computeroutput"><span class="identifier">B</span></code>. |
| When valid, <code class="computeroutput"><span class="identifier">enable_if_c</span><span class="special"><</span><span class="identifier">B</span><span class="special">,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span></code> |
| equals <code class="computeroutput"><span class="identifier">T</span></code>. The <code class="computeroutput"><span class="identifier">enable_if_c</span></code> template can thus be used for |
| controlling when functions are considered for overload resolution and when |
| they are not. For example, the following function is defined for all arithmetic |
| types (according to the classification of the Boost <span class="bold"><strong>type_traits</strong></span> |
| library): |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if_c</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">t</span><span class="special">;</span> <span class="special">}</span> |
| </pre> |
| <p> |
| The <code class="computeroutput"><span class="identifier">disable_if_c</span></code> template |
| is provided as well, and has the same functionality as <code class="computeroutput"><span class="identifier">enable_if_c</span></code> |
| except for the negated condition. The following function is enabled for all |
| non-arithmetic types. |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">disable_if_c</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">bar</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">t</span><span class="special">;</span> <span class="special">}</span> |
| </pre> |
| <p> |
| For easier syntax in some cases and interoperation with Boost.MPL we provide |
| versions of the <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| templates taking any type with a <code class="computeroutput"><span class="keyword">bool</span></code> |
| member constant named <code class="computeroutput"><span class="identifier">value</span></code> |
| as the condition argument. The MPL <code class="computeroutput"><span class="identifier">bool_</span></code>, |
| <code class="computeroutput"><span class="identifier">and_</span></code>, <code class="computeroutput"><span class="identifier">or_</span></code>, |
| and <code class="computeroutput"><span class="identifier">not_</span></code> templates are likely |
| to be useful for creating such types. Also, the traits classes in the Boost.Type_traits |
| library follow this convention. For example, the above example function |
| <code class="computeroutput"><span class="identifier">foo</span></code> can be alternatively |
| written as: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">t</span><span class="special">;</span> <span class="special">}</span> |
| </pre> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="core.enable_if.using_enable_if"></a><a class="link" href="enable_if.html#core.enable_if.using_enable_if" title="Using enable_if">Using enable_if</a> |
| </h3></div></div></div> |
| <p> |
| The <code class="computeroutput"><span class="identifier">enable_if</span></code> templates are |
| defined in <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">enable_if</span><span class="special">.</span><span class="identifier">hpp</span></code>, which is included by <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">.</span><span class="identifier">hpp</span></code>. |
| </p> |
| <p> |
| With respect to function templates, <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| can be used in multiple different ways: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| As the return type of an instantiatied function |
| </li> |
| <li class="listitem"> |
| As an extra parameter of an instantiated function |
| </li> |
| <li class="listitem"> |
| As an extra template parameter (useful only in a compiler that supports |
| C++0x default arguments for function template parameters, see <a class="link" href="enable_if.html#core.enable_if.using_enable_if.enable_if_0x" title="Enabling function templates in C++0x">Enabling |
| function templates in C++0x</a> for details. |
| </li> |
| </ul></div> |
| <p> |
| In the previous section, the return type form of <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| was shown. As an example of using the form of <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| that works via an extra function parameter, the <code class="computeroutput"><span class="identifier">foo</span></code> |
| function in the previous section could also be written as: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="identifier">T</span> <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">,</span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">*</span> <span class="identifier">dummy</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span> |
| </pre> |
| <p> |
| Hence, an extra parameter of type <code class="computeroutput"><span class="keyword">void</span><span class="special">*</span></code> is added, but it is given a default value |
| to keep the parameter hidden from client code. Note that the second template |
| argument was not given to <code class="computeroutput"><span class="identifier">enable_if</span></code>, |
| as the default <code class="computeroutput"><span class="keyword">void</span></code> gives the |
| desired behavior. |
| </p> |
| <p> |
| Which way to write the enabler is largely a matter of taste, but for certain |
| functions, only a subset of the options is possible: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| Many operators have a fixed number of arguments, thus <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| must be used either in the return type or in an extra template parameter. |
| </li> |
| <li class="listitem"> |
| Functions that have a variadic parameter list must use either the return |
| type form or an extra template parameter. |
| </li> |
| <li class="listitem"> |
| Constructors do not have a return type so you must use either an extra |
| function parameter or an extra template parameter. |
| </li> |
| <li class="listitem"> |
| Constructors that have a variadic parameter list must an extra template |
| parameter. |
| </li> |
| <li class="listitem"> |
| Conversion operators can only be written with an extra template parameter. |
| </li> |
| </ul></div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.using_enable_if.enable_if_0x"></a><a class="link" href="enable_if.html#core.enable_if.using_enable_if.enable_if_0x" title="Enabling function templates in C++0x">Enabling |
| function templates in C++0x</a> |
| </h4></div></div></div> |
| <p> |
| In a compiler which supports C++0x default arguments for function template |
| parameters, you can enable and disable function templates by adding an |
| additional template parameter. This approach works in all situations where |
| you would use either the return type form of <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| or the function parameter form, including operators, constructors, variadic |
| function templates, and even overloaded conversion operations. |
| </p> |
| <p> |
| As an example: |
| </p> |
| <pre class="programlisting"><span class="preprocessor">#include</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">is_arithmetic</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> |
| <span class="preprocessor">#include</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">is_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> |
| <span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">enable_if</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> |
| |
| <span class="keyword">class</span> <span class="identifier">test</span> |
| <span class="special">{</span> |
| <span class="keyword">public</span><span class="special">:</span> |
| <span class="comment">// A constructor that works for any argument list of size 10</span> |
| <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">T</span><span class="special">,</span> |
| <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if_c</span><span class="special"><</span> <span class="keyword">sizeof</span><span class="special">...(</span> <span class="identifier">T</span> <span class="special">)</span> <span class="special">==</span> <span class="number">10</span><span class="special">,</span> |
| <span class="keyword">int</span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">=</span> <span class="number">0</span><span class="special">></span> |
| <span class="identifier">test</span><span class="special">(</span> <span class="identifier">T</span><span class="special">&&...</span> <span class="special">);</span> |
| |
| <span class="comment">// A conversion operation that can convert to any arithmetic type</span> |
| <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> |
| <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span> <span class="identifier">T</span> <span class="special">>,</span> |
| <span class="keyword">int</span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">=</span> <span class="number">0</span><span class="special">></span> |
| <span class="keyword">operator</span> <span class="identifier">T</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span> |
| |
| <span class="comment">// A conversion operation that can convert to any pointer type</span> |
| <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> |
| <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_pointer</span><span class="special"><</span> <span class="identifier">T</span> <span class="special">>,</span> |
| <span class="keyword">int</span> <span class="special">>::</span><span class="identifier">type</span> <span class="special">=</span> <span class="number">0</span><span class="special">></span> |
| <span class="keyword">operator</span> <span class="identifier">T</span><span class="special">()</span> <span class="keyword">const</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="comment">// Works</span> |
| <span class="identifier">test</span> <span class="identifier">test_</span><span class="special">(</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">,</span> <span class="number">10</span> <span class="special">);</span> |
| |
| <span class="comment">// Fails as expected</span> |
| <span class="identifier">test</span> <span class="identifier">fail_construction</span><span class="special">(</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span> <span class="special">);</span> |
| |
| <span class="comment">// Works by calling the conversion operator enabled for arithmetic types</span> |
| <span class="keyword">int</span> <span class="identifier">arithmetic_object</span> <span class="special">=</span> <span class="identifier">test_</span><span class="special">;</span> |
| |
| <span class="comment">// Works by calling the conversion operator enabled for pointer types</span> |
| <span class="keyword">int</span><span class="special">*</span> <span class="identifier">pointer_object</span> <span class="special">=</span> <span class="identifier">test_</span><span class="special">;</span> |
| |
| <span class="comment">// Fails as expected</span> |
| <span class="keyword">struct</span> <span class="special">{}</span> <span class="identifier">fail_conversion</span> <span class="special">=</span> <span class="identifier">test_</span><span class="special">;</span> |
| <span class="special">}</span> |
| </pre> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.using_enable_if.enabling_template_class_speciali"></a><a class="link" href="enable_if.html#core.enable_if.using_enable_if.enabling_template_class_speciali" title="Enabling template class specializations">Enabling |
| template class specializations</a> |
| </h4></div></div></div> |
| <p> |
| Class template specializations can be enabled or disabled with <code class="computeroutput"><span class="identifier">enable_if</span></code>. One extra template parameter |
| needs to be added for the enabler expressions. This parameter has the default |
| value <code class="computeroutput"><span class="keyword">void</span></code>. For example: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Enable</span> <span class="special">=</span> <span class="keyword">void</span><span class="special">></span> |
| <span class="keyword">class</span> <span class="identifier">A</span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">class</span> <span class="identifier">A</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">class</span> <span class="identifier">A</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">is_float</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span><span class="special">></span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span> |
| </pre> |
| <p> |
| Instantiating <code class="computeroutput"><span class="identifier">A</span></code> with any |
| integral type matches the first specialization, whereas any floating point |
| type matches the second one. All other types match the primary template. |
| The condition can be any compile-time boolean expression that depends on |
| the template arguments of the class. Note that again, the second argument |
| to <code class="computeroutput"><span class="identifier">enable_if</span></code> is not needed; |
| the default (<code class="computeroutput"><span class="keyword">void</span></code>) is the |
| correct value. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.using_enable_if.overlapping_enabler_conditions"></a><a class="link" href="enable_if.html#core.enable_if.using_enable_if.overlapping_enabler_conditions" title="Overlapping enabler conditions">Overlapping |
| enabler conditions</a> |
| </h4></div></div></div> |
| <p> |
| Once the compiler has examined the enabling conditions and included the |
| function into the overload resolution set, normal C++ overload resolution |
| rules are used to select the best matching function. In particular, there |
| is no ordering between enabling conditions. Function templates with enabling |
| conditions that are not mutually exclusive can lead to ambiguities. For |
| example: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_integral</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="keyword">void</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{}</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="keyword">void</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{}</span> |
| </pre> |
| <p> |
| All integral types are also arithmetic. Therefore, say, for the call <code class="computeroutput"><span class="identifier">foo</span><span class="special">(</span><span class="number">1</span><span class="special">)</span></code>, both |
| conditions are true and both functions are thus in the overload resolution |
| set. They are both equally good matches and thus ambiguous. Of course, |
| more than one enabling condition can be simultaneously true as long as |
| other arguments disambiguate the functions. |
| </p> |
| <p> |
| The above discussion applies to using <code class="computeroutput"><span class="identifier">enable_if</span></code> |
| in class template partial specializations as well. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.using_enable_if.enable_if_lazy"></a><a class="link" href="enable_if.html#core.enable_if.using_enable_if.enable_if_lazy" title="Lazy enable_if">Lazy |
| enable_if</a> |
| </h4></div></div></div> |
| <p> |
| In some cases it is necessary to avoid instantiating part of a function |
| signature unless an enabling condition is true. For example: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">class</span> <span class="identifier">mult_traits</span><span class="special">;</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">is_multipliable</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">>,</span> |
| <span class="keyword">typename</span> <span class="identifier">mult_traits</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">>::</span><span class="identifier">type</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="keyword">operator</span><span class="special">*(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">u</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span> |
| </pre> |
| <p> |
| Assume the class template <code class="computeroutput"><span class="identifier">mult_traits</span></code> |
| is a traits class defining the resulting type of a multiplication operator. |
| The <code class="computeroutput"><span class="identifier">is_multipliable</span></code> traits |
| class specifies for which types to enable the operator. Whenever <code class="computeroutput"><span class="identifier">is_multipliable</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">>::</span><span class="identifier">value</span></code> |
| is <code class="computeroutput"><span class="keyword">true</span></code> for some types <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>, |
| then <code class="computeroutput"><span class="identifier">mult_traits</span><span class="special"><</span><span class="identifier">A</span><span class="special">,</span> <span class="identifier">B</span><span class="special">>::</span><span class="identifier">type</span></code> |
| is defined. |
| </p> |
| <p> |
| Now, trying to invoke (some other overload) of <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> with, say, operand types <code class="computeroutput"><span class="identifier">C</span></code> and <code class="computeroutput"><span class="identifier">D</span></code> |
| for which <code class="computeroutput"><span class="identifier">is_multipliable</span><span class="special"><</span><span class="identifier">C</span><span class="special">,</span> <span class="identifier">D</span><span class="special">>::</span><span class="identifier">value</span></code> is <code class="computeroutput"><span class="keyword">false</span></code> |
| and <code class="computeroutput"><span class="identifier">mult_traits</span><span class="special"><</span><span class="identifier">C</span><span class="special">,</span> <span class="identifier">D</span><span class="special">>::</span><span class="identifier">type</span></code> |
| is not defined is an error on some compilers. The SFINAE principle is not |
| applied because the invalid type occurs as an argument to another template. |
| The <code class="computeroutput"><span class="identifier">lazy_enable_if</span></code> and |
| <code class="computeroutput"><span class="identifier">lazy_disable_if</span></code> templates |
| (and their <code class="computeroutput"><span class="identifier">_c</span></code> versions) |
| can be used in such situations: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">lazy_enable_if</span><span class="special"><</span><span class="identifier">is_multipliable</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">>,</span> |
| <span class="identifier">mult_traits</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">></span> <span class="special">>::</span><span class="identifier">type</span> |
| <span class="keyword">operator</span><span class="special">*(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">U</span><span class="special">&</span> <span class="identifier">u</span><span class="special">)</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span> |
| </pre> |
| <p> |
| The second argument of <code class="computeroutput"><span class="identifier">lazy_enable_if</span></code> |
| must be a class type that defines a nested type named <code class="computeroutput"><span class="identifier">type</span></code> |
| whenever the first parameter (the condition) is true. |
| </p> |
| <div class="note"><table border="0" summary="Note"> |
| <tr> |
| <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> |
| <th align="left">Note</th> |
| </tr> |
| <tr><td align="left" valign="top"><p> |
| Referring to one member type or static constant in a traits class causes |
| all of the members (type and static constant) of that specialization |
| to be instantiated. Therefore, if your traits classes can sometimes contain |
| invalid types, you should use two distinct templates for describing the |
| conditions and the type mappings. In the above example, <code class="computeroutput"><span class="identifier">is_multipliable</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">>::</span><span class="identifier">value</span></code> defines when <code class="computeroutput"><span class="identifier">mult_traits</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">>::</span><span class="identifier">type</span></code> |
| is valid. |
| </p></td></tr> |
| </table></div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h4 class="title"> |
| <a name="core.enable_if.using_enable_if.compiler_workarounds"></a><a class="link" href="enable_if.html#core.enable_if.using_enable_if.compiler_workarounds" title="Compiler workarounds">Compiler |
| workarounds</a> |
| </h4></div></div></div> |
| <p> |
| Some compilers flag functions as ambiguous if the only distinguishing factor |
| is a different condition in an enabler (even though the functions could |
| never be ambiguous). For example, some compilers (e.g. GCC 3.2) diagnose |
| the following two functions as ambiguous: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">);</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">disable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">);</span> |
| </pre> |
| <p> |
| Two workarounds can be applied: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| <p class="simpara"> |
| Use an extra dummy parameter which disambiguates the functions. Use |
| a default value for it to hide the parameter from the caller. For example: |
| </p> |
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">struct</span> <span class="identifier">dummy</span> <span class="special">{</span> <span class="identifier">dummy</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">{}</span> <span class="special">};</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">dummy</span><span class="special"><</span><span class="number">0</span><span class="special">></span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span> |
| |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">disable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">dummy</span><span class="special"><</span><span class="number">1</span><span class="special">></span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span> |
| </pre> |
| </li> |
| <li class="listitem"> |
| <p class="simpara"> |
| Define the functions in different namespaces and bring them into a |
| common namespace with <code class="computeroutput"><span class="keyword">using</span></code> |
| declarations: |
| </p> |
| <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">A</span> <span class="special">{</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">enable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">);</span> |
| <span class="special">}</span> |
| |
| <span class="keyword">namespace</span> <span class="identifier">B</span> <span class="special">{</span> |
| <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> |
| <span class="keyword">typename</span> <span class="identifier">disable_if</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_arithmetic</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</span> <span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> |
| <span class="identifier">foo</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">t</span><span class="special">);</span> |
| <span class="special">}</span> |
| |
| <span class="keyword">using</span> <span class="identifier">A</span><span class="special">::</span><span class="identifier">foo</span><span class="special">;</span> |
| <span class="keyword">using</span> <span class="identifier">B</span><span class="special">::</span><span class="identifier">foo</span><span class="special">;</span> |
| </pre> |
| <p class="simpara"> |
| Note that the second workaround above cannot be used for member templates. |
| On the other hand, operators do not accept extra arguments, which makes |
| the first workaround unusable. As the net effect, neither of the workarounds |
| are of assistance for templated operators that need to be defined as |
| member functions (assignment and subscript operators). |
| </p> |
| </li> |
| </ul></div> |
| </div> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="core.enable_if.acknowledgements"></a><a class="link" href="enable_if.html#core.enable_if.acknowledgements" title="Acknowledgements">Acknowledgements</a> |
| </h3></div></div></div> |
| <p> |
| We are grateful to Howard Hinnant, Jason Shirk, Paul Mensonides, and Richard |
| Smith whose findings have influenced the library. |
| </p> |
| </div> |
| <div class="section"> |
| <div class="titlepage"><div><div><h3 class="title"> |
| <a name="core.enable_if.references"></a><a class="link" href="enable_if.html#core.enable_if.references" title="References">References</a> |
| </h3></div></div></div> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> |
| <li class="listitem"> |
| <a name="REF1"></a>[1] Jaakko Järvi, Jeremiah Willcock, Howard Hinnant, |
| and Andrew Lumsdaine. Function overloading based on arbitrary properties |
| of types. <span class="emphasis"><em>C++ Users Journal</em></span>, 21(6):25--32, June |
| 2003. |
| </li> |
| <li class="listitem"> |
| <a name="REF2"></a>[2] Jaakko Järvi, Jeremiah Willcock, and Andrew |
| Lumsdaine. Concept-controlled polymorphism. In Frank Pfennig and Yannis |
| Smaragdakis, editors, <span class="emphasis"><em>Generative Programming and Component |
| Engineering</em></span>, volume 2830 of <span class="emphasis"><em>LNCS</em></span>, pages |
| 228--244. Springer Verlag, September 2003. |
| </li> |
| <li class="listitem"> |
| <a name="REF3"></a>[3] David Vandevoorde and Nicolai M. Josuttis. <span class="emphasis"><em>C++ |
| Templates: The Complete Guide</em></span>. Addison-Wesley, 2002. |
| </li> |
| </ul></div> |
| </div> |
| </div> |
| <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> |
| <td align="left"></td> |
| <td align="right"><div class="copyright-footer">Copyright © 2014 Peter Dimov<br>Copyright © 2014 Glen Fernandes<br>Copyright © 2014 Andrey Semashev<p> |
| Distributed under the <a href="http://boost.org/LICENSE_1_0.txt" target="_top">Boost |
| Software License, Version 1.0</a>. |
| </p> |
| </div></td> |
| </tr></table> |
| <hr> |
| <div class="spirit-nav"> |
| <a accesskey="p" href="demangle.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="explicit_operator_bool.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> |
| </div> |
| </body> |
| </html> |