1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 4 5<html xmlns="http://www.w3.org/1999/xhtml"> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 8 9 <title>FAQ — Boost.HigherOrderFunctions 0.6 documentation</title> 10 11 <link rel="stylesheet" href="../../_static/boostbook.css" type="text/css" /> 12 <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> 13 14 <script type="text/javascript"> 15 var DOCUMENTATION_OPTIONS = { 16 URL_ROOT: '../../', 17 VERSION: '0.6', 18 COLLAPSE_INDEX: false, 19 FILE_SUFFIX: '.html', 20 HAS_SOURCE: true, 21 SOURCELINK_SUFFIX: '.txt' 22 }; 23 </script> 24 <script type="text/javascript" src="../../_static/jquery.js"></script> 25 <script type="text/javascript" src="../../_static/underscore.js"></script> 26 <script type="text/javascript" src="../../_static/doctools.js"></script> 27 <link rel="index" title="Index" href="../../genindex.html" /> 28 <link rel="search" title="Search" href="../../search.html" /> 29 <link rel="next" title="Acknowledgements" href="acknowledgements.html" /> 30 <link rel="prev" title="Partial function evaluation" href="partialfunctions.html" /> 31 </head> 32 <body role="document"> 33<table cellpadding="2" width="100%"><tr> 34<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86"src="../../_static/boost.png"></td> 35</tr></table> 36 37<div class="spirit-nav"> 38<a accesskey="p" href="partialfunctions.html"><img src="../../_static/prev.png" alt="Prev"></a> 39<a accesskey="u" href="discussion.html"><img src="../../_static/up.png" alt="Up"></a> 40<a accesskey="h" href="../index.html"><img src="../../_static/home.png" alt="Home"></a> 41<a accesskey="n" href="acknowledgements.html"><img src="../../_static/next.png" alt="Next"></a> 42</div> 43 44 45 <div class="document"> 46 <div class="chapter"> 47 <div class="body" role="main"> 48 49 <!-- Copyright 2018 Paul Fultz II 50 Distributed under the Boost Software License, Version 1.0. 51 (http://www.boost.org/LICENSE_1_0.txt) 52--><div class="section" id="faq"> 53<h1>FAQ<a class="headerlink" href="#faq" title="Permalink to this headline">¶</a></h1> 54<div class="section" id="q-why-is-const-required-for-the-call-operator-on-function-objects"> 55<h2>Q: Why is <code class="docutils literal"><span class="pre">const</span></code> required for the call operator on function objects?<a class="headerlink" href="#q-why-is-const-required-for-the-call-operator-on-function-objects" title="Permalink to this headline">¶</a></h2> 56<p>Mutable function objects are not prohibited, they just need to be explicit by 57using the adaptor <a class="reference internal" href="../../include/boost/hof/mutable.html"><span class="doc">mutable</span></a>. The main reason for this, is that it can lead to 58many suprising behaviours. Many times function objects are copied by value 59everywhere. For example,</p> 60<div class="highlight-cpp"><div class="highlight"><pre><span class="k">struct</span> <span class="n">counter</span> 61<span class="p">{</span> 62 <span class="kt">int</span> <span class="n">i</span><span class="p">;</span> 63 <span class="n">counter</span><span class="p">()</span> <span class="o">:</span> <span class="n">i</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> 64 <span class="p">{}</span> 65 66 <span class="k">template</span><span class="o"><</span><span class="n">class</span><span class="p">...</span> <span class="n">Ts</span><span class="o">></span> 67 <span class="kt">int</span> <span class="k">operator</span><span class="p">()(</span><span class="n">Ts</span><span class="o">&&</span><span class="p">...)</span> 68 <span class="p">{</span> 69 <span class="k">return</span> <span class="n">i</span><span class="o">++</span><span class="p">;</span> 70 <span class="p">}</span> 71<span class="p">};</span> 72 73 74<span class="n">counter</span> <span class="n">c</span><span class="p">{};</span> 75<span class="n">proj</span><span class="p">(</span><span class="n">mutable_</span><span class="p">(</span><span class="n">c</span><span class="p">))(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span> 76<span class="c1">// Prints 0, not 2</span> 77<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">c</span><span class="p">.</span><span class="n">i</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> 78</pre></div> 79</div> 80<p>The example won’t ever yield the expected value, because the function mutates 81a copy of the objects. Instead, <code class="docutils literal"><span class="pre">std::ref</span></code> should be used:</p> 82<div class="highlight-cpp"><div class="highlight"><pre><span class="n">counter</span> <span class="n">c</span><span class="p">{};</span> 83<span class="n">proj</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">c</span><span class="p">))(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span> 84<span class="c1">// Prints 2</span> 85<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">c</span><span class="p">.</span><span class="n">i</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> 86</pre></div> 87</div> 88<p>Which will print the expected value.</p> 89<p>Another reason why <code class="docutils literal"><span class="pre">const</span></code> is required is because of supporting <code class="docutils literal"><span class="pre">constexpr</span></code> on 90C++11 compilers. In C++11, <code class="docutils literal"><span class="pre">constexpr</span></code> implies <code class="docutils literal"><span class="pre">const</span></code>, so it would be 91impossible to provide a non-const overload for functions that is <code class="docutils literal"><span class="pre">constexpr</span></code>. 92Instead, <code class="docutils literal"><span class="pre">constexpr</span></code> would have to be made explicit. Considering the pitfalls 93of mutable function objects, it would be better to make mutability explicit 94rather than <code class="docutils literal"><span class="pre">constexpr</span></code>.</p> 95</div> 96<div class="section" id="q-is-the-reinterpret-cast-in-boost-hof-static-lambda-undefined-behaviour"> 97<h2>Q: Is the reinterpret cast in BOOST_HOF_STATIC_LAMBDA undefined behaviour?<a class="headerlink" href="#q-is-the-reinterpret-cast-in-boost-hof-static-lambda-undefined-behaviour" title="Permalink to this headline">¶</a></h2> 98<p>Not really, since the objects are empty, there is no data access. There is a 99static assert to guard against this restriction.</p> 100<p>Now there could be an insane implementation where this doesn’t work(perhaps 101the lambdas are not empty for some strange reason), which the library would 102have to apply a different technique to make it work. However, this is quite 103unlikely considering that C++ will probably get constexpr lambdas and inline 104variables in the future.</p> 105<p>Alternatively, the factory pattern can be used instead of 106<a class="reference internal" href="../../include/boost/hof/lambda.html#boost-hof-static-lambda-function"><span class="std std-ref">BOOST_HOF_STATIC_LAMBDA_FUNCTION</span></a>, which doesn’t require an reinterpret cast:</p> 107<div class="highlight-cpp"><div class="highlight"><pre><span class="k">struct</span> <span class="n">sum_factory</span> 108<span class="p">{</span> 109 <span class="k">auto</span> <span class="k">operator</span><span class="o">*</span><span class="p">()</span> <span class="k">const</span> 110 <span class="p">{</span> 111 <span class="k">return</span> <span class="p">[](</span><span class="k">auto</span> <span class="n">x</span><span class="p">,</span> <span class="k">auto</span> <span class="n">y</span><span class="p">)</span> 112 <span class="p">{</span> 113 <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="p">;</span> 114 <span class="p">};</span> 115 <span class="p">}</span> 116<span class="p">}</span> 117 118<span class="n">BOOST_HOF_STATIC_FUNCTION</span><span class="p">(</span><span class="n">sum</span><span class="p">)</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">hof</span><span class="o">::</span><span class="n">indirect</span><span class="p">(</span><span class="n">sum_factory</span><span class="p">{});</span> 119</pre></div> 120</div> 121</div> 122</div> 123 124 125 </div> 126 </div> 127 <div class="clearer"></div> 128 </div> 129 <div class="footer" role="contentinfo"> 130 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 131 <td align="left"></td> 132 <td align="right"><div class="copyright-footer"> 133 © Copyright 2016, Paul Fultz II. 134 135 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.5.6. 136 <p>Distributed under the Boost Software License, Version 1.0. 137 (See accompanying file <code class="filename">LICENSE_1_0.txt</code> or copy at 138 <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) 139 </p> 140 </div></td> 141 </tr></table> 142 </div> 143 </body> 144</html>