| <?xml version="1.0" encoding="utf-8" ?> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <!-- Copyright Aleksey Gurtovoy 2006. Distributed under the Boost --> |
| <!-- Software License, Version 1.0. (See accompanying --> |
| <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| <meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" /> |
| <title>THE BOOST MPL LIBRARY: Placeholders</title> |
| <link rel="stylesheet" href="../style.css" type="text/css" /> |
| </head> |
| <body class="docframe"> |
| <table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./lambda-details.html" class="navigation-link">Prev</a> <a href="./placeholder-expression.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group">Back <a href="./placeholder-expression.html" class="navigation-link">Along</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./lambda-details.html" class="navigation-link">Up</a> <a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td> |
| <td class="header-group page-location"><a href="../index.html" class="navigation-link">Front Page</a> / <a href="./tutorial-metafunctions.html" class="navigation-link">Tutorial: Metafunctions and Higher-Order Metaprogramming</a> / <a href="./lambda-details.html" class="navigation-link">Lambda Details</a> / <a href="./placeholders.html" class="navigation-link">Placeholders</a></td> |
| </tr></table><div class="header-separator"></div> |
| <div class="section" id="placeholders"> |
| <h1><a class="toc-backref" href="./lambda-details.html#id55" name="placeholders">Placeholders</a></h1> |
| <p>The definition of "placeholder" may surprise you:</p> |
| <div class="admonition-definition admonition"> |
| <p class="admonition-title first">Definition</p> |
| <p>A <strong>placeholder</strong> is a metafunction class of the form <tt class="literal"><span class="pre">mpl::arg<X></span></tt>.</p> |
| </div> |
| <div class="section" id="implementation"> |
| <h2><a name="implementation">Implementation</a></h2> |
| <p>The convenient names <tt class="literal"><span class="pre">_1</span></tt>, <tt class="literal"><span class="pre">_2</span></tt>,... <tt class="literal"><span class="pre">_5</span></tt> are actually |
| <tt class="literal"><span class="pre">typedef</span></tt>s for specializations of <tt class="literal"><span class="pre">mpl::arg</span></tt> that simply |
| select the <em>N</em>th argument for any <em>N</em>. <a class="footnote-reference" href="#config" id="id12" name="id12">[6]</a> The |
| implementation of placeholders looks something like this:</p> |
| <table class="footnote" frame="void" id="config" rules="none"> |
| <colgroup><col class="label" /><col /></colgroup> |
| <tbody valign="top"> |
| <tr><td class="label"><a class="fn-backref" href="#id12" name="config">[6]</a></td><td>MPL provides five placeholders by default. See |
| the Configuration Macros section of <a class="reference" href="./reference-manual.html">the MPL reference manual</a> for a |
| description of how to change the number of placeholders |
| provided.</td></tr> |
| </tbody> |
| </table> |
| <pre class="literal-block"> |
| namespace boost { namespace mpl { namespace placeholders { |
| |
| template <int N> struct arg; // forward declarations |
| struct void_; |
| |
| template <> |
| struct arg<<strong>1</strong>> |
| { |
| template < |
| class <strong>A1</strong>, class A2 = void_, ... class A<em>m</em> = void_> |
| struct apply |
| { |
| typedef <strong>A1</strong> type; // return the first argument |
| }; |
| }; |
| typedef <strong>arg<1> _1</strong>; |
| |
| template <> |
| struct arg<<strong>2</strong>> |
| { |
| template < |
| class A1, class <strong>A2</strong>, class A3 = void_, ...class A<em>m</em> = void_ |
| > |
| struct apply |
| { |
| typedef <strong>A2</strong> type; // return the second argument |
| }; |
| }; |
| typedef <strong>arg<2> _2</strong>; |
| |
| <em>more specializations and typedefs...</em> |
| |
| }}} |
| </pre> |
| <!-- @example.replace('...','') --> |
| <p>Remember that invoking a metafunction class is the same as invoking |
| its nested <tt class="literal"><span class="pre">apply</span></tt> metafunction. When a placeholder in a lambda |
| expression is evaluated, it is invoked on the expression's actual |
| arguments, returning just one of them. The results are then |
| substituted back into the lambda expression and the evaluation |
| process continues.</p> |
| </div> |
| <div class="section" id="the-unnamed-placeholder"> |
| <h2><a name="the-unnamed-placeholder">The Unnamed Placeholder</a></h2> |
| <p>There's one special placeholder, known as the <strong>unnamed |
| placeholder</strong>, that we haven't yet defined:</p> |
| <pre class="literal-block"> |
| namespace boost { namespace mpl { namespace placeholders { |
| |
| <strong>typedef arg<-1> _;</strong> // the unnamed placeholder |
| |
| }}} |
| </pre> |
| <!-- @ stack[-2].prepend('namespace shield {') |
| example.append('}') # so we don't conflict with the prefix |
| compile('all') --> |
| <p>The details of its implementation aren't important; all you really |
| need to know about the unnamed placeholder is that it gets special |
| treatment. When a lambda expression is being transformed into a |
| metafunction class by <tt class="literal"><span class="pre">mpl::lambda</span></tt>,</p> |
| <blockquote> |
| the <em>n</em>th appearance of the unnamed placeholder <em>in a given |
| template specialization</em> is replaced with <tt class="literal"><span class="pre">_</span></tt><em>n</em>.</blockquote> |
| <p>So, for example, every row of Table 1.1 |
| below contains two equivalent lambda expressions.</p> |
| <table border="1" class="table"> |
| <caption>Unnamed Placeholder Semantics</caption> |
| <colgroup> |
| <col width="48%" /> |
| <col width="52%" /> |
| </colgroup> |
| <tbody valign="top"> |
| <tr><td><pre class="first last literal-block"> |
| mpl::plus<_,_> |
| </pre> |
| </td> |
| <td><pre class="first last literal-block"> |
| mpl::plus<_1,_2> |
| </pre> |
| </td> |
| </tr> |
| <tr><td><pre class="first last literal-block"> |
| boost::is_same< |
| _ |
| , boost::add_pointer<_> |
| > |
| </pre> |
| </td> |
| <td><pre class="first last literal-block"> |
| boost::is_same< |
| _1 |
| , boost::add_pointer<_1> |
| > |
| </pre> |
| </td> |
| </tr> |
| <tr><td><pre class="first last literal-block"> |
| mpl::multiplies< |
| mpl::plus<_,_> |
| , mpl::minus<_,_> |
| > |
| </pre> |
| </td> |
| <td><pre class="first last literal-block"> |
| mpl::multiplies< |
| mpl::plus<_1,_2> |
| , mpl::minus<_1,_2> |
| > |
| </pre> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| <!-- @ for n in range(len(stack)): |
| stack[n].wrap('typedef ', 'type%d;' % n) |
| compile('all') --> |
| <p>Especially when used in simple lambda expressions, the unnamed |
| placeholder often eliminates just enough syntactic "noise" to |
| significantly improve readability.</p> |
| </div> |
| </div> |
| |
| <div class="footer-separator"></div> |
| <table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./lambda-details.html" class="navigation-link">Prev</a> <a href="./placeholder-expression.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group">Back <a href="./placeholder-expression.html" class="navigation-link">Along</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./lambda-details.html" class="navigation-link">Up</a> <a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td> |
| </tr></table></body> |
| </html> |