]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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: Incomplete Support for Lambda Expressions</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="./broken-integral-constant.html" class="navigation-link">Prev</a> <a href="./eti.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./broken-integral-constant.html" class="navigation-link">Back</a> <a href="./eti.html" class="navigation-link">Along</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./portability.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="./technical-details.html" class="navigation-link">Technical Details</a> / <a href="./portability.html" class="navigation-link">Portability</a> / <a href="./incomplete-support-for.html" class="navigation-link">Incomplete Support for Lambda Expressions</a></td> | |
16 | </tr></table><div class="header-separator"></div> | |
17 | <div class="section" id="incomplete-support-for"> | |
18 | <h1><a class="toc-backref" href="./portability.html#id75" name="incomplete-support-for">Incomplete Support for Lambda Expressions</a></h1> | |
19 | <p>Seasoned MPL users will agree with us that if there is | |
20 | anything in the MPL that is seemingly magical both in power and | |
21 | its nature, then it's MPL lambda expressions. In reality, the | |
22 | mechanism that bring this to life is very straightforward and | |
23 | probably can be explained to anyone generally familiar with C++ | |
24 | templates in less than 10 minutes.</p> | |
25 | <!-- People are going to hate you for saying so and not actually --> | |
26 | <!-- explaining it. --> | |
27 | <p>Unfortunately, this mechanism also happens to rely on support for | |
28 | partial template specialization and template template parameters. | |
29 | Among the so-called deficient compilers — basically, most of the | |
30 | compilers released before the year 2000 — the chances are poor | |
31 | that you'll find <em>complete</em> support for <em>both</em> of these features. | |
32 | Please see our <a class="reference" href="./portability.html#compatibility-table">compatibility table</a> for the list of the products | |
33 | which fall into this category.</p> | |
34 | <p>Although it's not possible to implement <em>fully transparent</em> lambda | |
35 | expressions without these two features, a slightly more limited | |
36 | implementation that requires some manual assistance from the | |
37 | metafunction author is possible. This section describes the manual | |
38 | work required and the limitations of the result.</p> | |
39 | <div class="section" id="incomplete-the-problem"> | |
40 | <h2><a name="incomplete-the-problem">The Problem</a></h2> | |
41 | <p>If your compiler falls into the "deficient" category, the following | |
42 | valid MPL metaprogram will fail to compile for you:</p> | |
43 | <pre class="literal-block"> | |
44 | #include <boost/mpl/apply.hpp> | |
45 | ||
46 | using namespace boost::mpl; | |
47 | ||
48 | template< typename T > struct add_const | |
49 | { | |
50 | typedef T const type; | |
51 | }; | |
52 | ||
53 | typedef apply1< add_const<_1>,int >::type t; // t == int const | |
54 | </pre> | |
55 | <p>Worse yet, chances are it wil fail with a diagnostic backtrace | |
56 | leading you into the inside of the library and possibly creating an | |
57 | impression that there's something's wrong there. The fact is, both | |
58 | the program and the library are defect free (for the | |
59 | purpose of this particular demonstraction), and it's your compiler | |
60 | that is to blame.</p> | |
61 | </div> | |
62 | <div class="section" id="incomplete-the-solution"> | |
63 | <h2><a name="incomplete-the-solution">The Solution</a></h2> | |
64 | <p>As previously mentioned, the solution requires some work from | |
65 | metafunction authors, but for the users of those metafunctions, the | |
66 | result is relatively transparent. Here's what we have to do to our | |
67 | earlier example:</p> | |
68 | <pre class="literal-block"> | |
69 | #include <boost/mpl/apply.hpp> | |
70 | <strong>#include <boost/mpl/aux_/lambda_support.hpp></strong> | |
71 | ||
72 | using namespace boost::mpl; | |
73 | ||
74 | template< typename T > struct add_const | |
75 | { | |
76 | typedef T const type; | |
77 | <strong>BOOST_MPL_AUX_LAMBDA_SUPPORT(1, add_const, (T))</strong> | |
78 | }; | |
79 | ||
80 | typedef apply1< add_const<_1>,int >::type t; // t == int const | |
81 | </pre> | |
82 | <p>With these two modifications, now the compiler that has been barking at us now | |
83 | happily accepts it. "Hey, that's not that bad at all!" you might say. Just put a | |
84 | little macro inside and be happy again.</p> | |
85 | </div> | |
86 | <div class="section" id="limitations"> | |
87 | <h2><a name="limitations">Limitations</a></h2> | |
88 | <p>Unfortunately, that's not quite the end of the story. There are | |
89 | still cases where the above approach will fail and we will have to | |
90 | resort to writing out-of-line metafunction class. Here are the | |
91 | details:</p> | |
92 | <blockquote> | |
93 | <p>To make the lambda expression work without partial template | |
94 | specialization and | |
95 | template template parameters, the MPL has to implement some other way of | |
96 | pulling apart the template instantiations' expression tree, and the only way | |
97 | to do it is through an intrusive metafunction introspection | |
98 | mechanism. That's what hidden behind the <tt class="literal"><span class="pre">BOOST_MPL_AUX_LAMBDA_SUPPORT</span></tt> macro | |
99 | we've seen above.</p> | |
100 | <p>But then, after we've got the information we need (the metafunction's arity | |
101 | and its exact template arguments) stored inside the metafunction itself, | |
102 | the only way for the library to access it is to look inside the metafunction. | |
103 | The latter, in its turn, means instantiating the metafunction, prematurely, | |
104 | before the actuall call, <em>with one or more placeholder arguments</em>. This last | |
105 | part is a potential problem.</p> | |
106 | </blockquote> | |
107 | <p>In other words, the mechanism works as long as your metafunction is | |
108 | "placeholder-safe" (can be safely instantiated on placeholder | |
109 | arguments), which comes down to the follwing two criteria:</p> | |
110 | <ol class="arabic simple"> | |
111 | <li>The metafunction doesn't access its arguments' nested members, or</li> | |
112 | <li>The only accessed members are types named <tt class="literal"><span class="pre">::tag</span></tt> or <tt class="literal"><span class="pre">::type</span></tt> (the | |
113 | placeholders do contain these).</li> | |
114 | </ol> | |
115 | <p>If these two hold, you can safely put <tt class="literal"><span class="pre">BOOST_MPL_AUX_LAMBDA_SUPPORT</span></tt> inside | |
116 | your metafunction and forget about the issue. If not, you are out of luck and | |
117 | probably have to write a metafunction class instead.</p> | |
118 | <p>The good news are that most of the MPL's own metafunctions and <a class="reference" href="../../../type_traits/index.html" target="_top">Boost.Type Traits</a> | |
119 | templates are "placeholder-safe" and have the workaround applied to them, so | |
120 | even on broken compilers things "just work" in about 90% of use cases.</p> | |
121 | <p>Please refer to the MPL <a class="reference" href="./reference-manual.html">reference manual</a> for the details on the | |
122 | <tt class="literal"><span class="pre">BOOST_MPL_AUX_LAMBDA_SUPPORT</span></tt> macro.</p> | |
123 | </div> | |
124 | </div> | |
125 | ||
126 | <div class="footer-separator"></div> | |
127 | <table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./broken-integral-constant.html" class="navigation-link">Prev</a> <a href="./eti.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./broken-integral-constant.html" class="navigation-link">Back</a> <a href="./eti.html" class="navigation-link">Along</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./portability.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> | |
128 | </tr></table></body> | |
129 | </html> |