1<?xml version="1.0" encoding="utf-8" ?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 4<!-- Copyright Aleksey Gurtovoy 2006. Distributed under the Boost --> 5<!-- Software License, Version 1.0. (See accompanying --> 6<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 7<head> 8<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 9<meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" /> 10<title>THE BOOST MPL LIBRARY: Placeholder Expression Definition</title> 11<link rel="stylesheet" href="../style.css" type="text/css" /> 12</head> 13<body class="docframe"> 14<table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./placeholders.html" class="navigation-link">Prev</a> <a href="./lambda-and-non.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./placeholders.html" class="navigation-link">Back</a> <a href="./lambda-and-non.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> 15<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="./placeholder-expression.html" class="navigation-link">Placeholder Expression Definition</a></td> 16</tr></table><div class="header-separator"></div> 17<div class="section" id="placeholder-expression"> 18<h1><a class="toc-backref" href="./lambda-details.html#id56" name="placeholder-expression">Placeholder Expression Definition</a></h1> 19<p>Now that you know just what <em>placeholder</em> means, we can define 20<em>placeholder expression</em>:</p> 21<div class="admonition-definition admonition"> 22<p class="admonition-title first">Definition</p> 23<p>A placeholder expression is either:</p> 24<blockquote> 25<blockquote> 26<ul class="simple"> 27<li>a placeholder</li> 28</ul> 29</blockquote> 30<p><em>or</em></p> 31<blockquote> 32<ul class="simple"> 33<li>a template specialization with at least one argument that 34is a placeholder expression.</li> 35</ul> 36</blockquote> 37</blockquote> 38</div> 39<p>In other words, a placeholder expression always involves a 40placeholder.</p> 41<!-- DWA: I'm still not sure we shouldn't be at least mentioning the 42pitfall, but for now it's commented out. 43 44Lambda and Nullary Metafunctions 45- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 46 47The definition of *placeholder expression* above has an interesting 48implication: an ordinary nullary metafunction is never a placeholder 49expression. In other words, even though ``add_pointer<int>`` is a 50nullary metafunction, it won't be invoked in the expression below; 51the assertion will always fail: 52 53.. parsed-literal:: 54 55 BOOST_STATIC_ASSERT(( 56 mpl::apply< 57 boost::is_same<**boost::add_pointer<int>**,_1> 58 , int\* 59 >::type::value 60 )); 61 62In order to allow a nullary metafunction to be used as a lambda 63expression, MPL provides this definition of ``arg``: 64 65.. parsed-literal:: 66 67 // primary template definition (not a specialization) 68 template <class F> 69 struct arg 70 { 71 template <class A1 = void\_, class A2 = void\_, ... class *Am* = void\_> 72 struct apply : F 73 { 74 }; 75 }; 76 77When applied to a lambda expression's actual arguments, ``arg<F>`` 78ignores them and simply returns ``F::type``. In other words, if 79``F`` is a nullary metafunction, ``arg<F>`` is a metafunction class 80that invokes ``F`` and returns the result. So we can transform 81add_pointer<int> into a placeholder and get the desired result 82with: 83 84.. parsed-literal:: 85 86 BOOST_STATIC_ASSERT(( 87 mpl::apply< 88 boost::is_same< 89 **mpl::arg<boost::add_pointer<int> >** 90 , _1 91 > 92 , int\* 93 >::type::value 94 )); --> 95</div> 96 97<div class="footer-separator"></div> 98<table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./placeholders.html" class="navigation-link">Prev</a> <a href="./lambda-and-non.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./placeholders.html" class="navigation-link">Back</a> <a href="./lambda-and-non.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> 99</tr></table></body> 100</html> 101