<li><aclass="reference"href="#defining-the-keywords"id="id9"name="id9">2.1<EFBFBD><EFBFBD><EFBFBD>Defining the keywords</a></li>
<li><aclass="reference"href="#defining-the-forwarding-functions"id="id10"name="id10">2.2<EFBFBD><EFBFBD><EFBFBD>Defining the forwarding functions</a></li>
<li><aclass="reference"href="#defining-the-implementation-function"id="id11"name="id11">2.3<EFBFBD><EFBFBD><EFBFBD>Defining the implementation function</a></li>
<p>First we define the named parameter keywords. This is done by creating
"tag" types for each keyword, and declaring <ttclass="literal"><spanclass="pre">keyword<</span></tt><em>tag</em><ttclass="literal"><spanclass="pre">></span></tt> objects:</p>
<h2><aclass="toc-backref"href="#id11"name="defining-the-implementation-function">2.3<EFBFBD><EFBFBD><EFBFBD>Defining the implementation function</a></h2>
<p>Because the keywords' <ttclass="literal"><spanclass="pre">operator=</span></tt> returns a temporary, and
temporaries cannot be bound to non-<ttclass="literal"><spanclass="pre">const</span></tt> reference parameters,
our forwarding functions need to take their arguments by <ttclass="literal"><spanclass="pre">const</span></tt>
reference <aclass="footnote-reference"href="#forwarding"id="id2"name="id2"><sup>1</sup></a>. As a result, an argument which is bound
to a keyword with <ttclass="literal"><spanclass="pre">operator=</span></tt> can be transparently passed by
non-const reference, but positional arguments are always passed by
<ttclass="literal"><spanclass="pre">const</span></tt> reference unless we use the <aclass="reference"href="../../bind/ref.hpp">Boost.Ref</a> library to
indicate otherwise:</p>
<preclass="literal-block">
#include <boost/ref.hpp>
float x;
foo(value = x); // held type is float&
foo(x); // held type is float const&, need help!
foo(boost::ref(x)); // held type is float&
</pre>
<p>Instances of <ttclass="literal"><spanclass="pre">boost::reference_wrapper<></span></tt> generated by
<ttclass="literal"><spanclass="pre">boost::ref</span></tt> will be unwrapped automatically by the library.</p>
<p>The parameters of our templated forwarding functions are completely
general; in fact, they're a perfect match for any argument type
whatsoever. The problems with exposing such general function
templates have been the subject of much discussion; especially in
the presence of <aclass="reference"href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#225">unqualified calls</a>. Probably the safest thing
to do is to isolate the forwarding functions in a namespace
containing no types <aclass="footnote-reference"href="#using"id="id3"name="id3"><sup>2</sup></a>, but often we'd <em>like</em> our functions
to play nicely with argument-dependent lookup and other function
overloads. In that case, it's neccessary to somehow remove the
functions from the overload set when the passed argument types
don't meet their needs.</p>
<p>This sort of overload control can be accomplished in C++ by taking
advantage of <aclass="reference"href="http://www.semantics.org/once_weakly/w02_SFINAE.pdf">SFINAE</a> (Substitution Failure Is Not An Error). If
type substitution during the instantiation of a function template
results in an invalid type, no compilation error is emitted;
instead the overload is removed from the overload set. By producing
an invalid type in the function signature depending on the result
of some condition, whether or not an overload is considered during
overload resolution can be controlled. The technique is formalized
in the <ttclass="literal"><spanclass="pre">enable_if</span></tt> utility.</p>
<p>The named parameters library provides built-in SFINAE support
through the following class template:</p>
<preclass="literal-block">
template<
class KeywordTag
, class HasDefaultValue // mpl::true_ or mpl::false_
<p>The key parameter, <ttclass="literal"><spanclass="pre">Predicate</span></tt> shall be a unary MPL lambda
expression or <aclass="reference"href="../../mpl/doc/ref/Metafunction_Class.html">Metafunction Class</a> that, when applied to the
actual type the argument, indicates whether that argument type
meets the function's requirements for that parameter position.</p>
<p>For example, let's say we want to restrict our <ttclass="literal"><spanclass="pre">foo()</span></tt> so that
the <ttclass="literal"><spanclass="pre">name</span></tt> parameter must be convertible to <ttclass="literal"><spanclass="pre">const</span><spanclass="pre">char*</span></tt>.
We'll replace our use of the <ttclass="literal"><spanclass="pre">name_t</span></tt> tag with a specialization
, <strong>foo_keywords::restrict<A0>::type x = foo_keywords()</strong>
)
{
foo_impl(x(a0));
}
template<class A0, class A1>
void foo(
const A0& a0, const A1& a1
, <strong>foo_keywords::restrict<A0,A1>::type x = foo_keywords()</strong>
)
{
foo_impl(x(a0, a1));
}
</pre>
<p>These additional parameters are not intended to be used directly
by callers; they merely trigger SFINAE by becoming illegal types
when the <ttclass="literal"><spanclass="pre">name</span></tt> argument is not convertible to <ttclass="literal"><spanclass="pre">const</span><spanclass="pre">char*</span></tt>.</p>
<tr><tdclass="label"><aclass="fn-backref"href="#id2"name="forwarding">[1]</a></td><td><p>One could provide overloads for <ttclass="literal"><spanclass="pre">const</span></tt> and
non-<ttclass="literal"><spanclass="pre">const</span></tt> reference versions of each parameter, but that
would quickly become unmanageable. It's known as "the
forwarding problem" and has been described in detail in this
<aclass="reference"href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">paper</a>. The combinatorial explosion is avoided for the
parameter of keywords' <ttclass="literal"><spanclass="pre">operator=</span></tt> because they take only a
Generated by <aclass="reference"href="http://docutils.sourceforge.net/">Docutils</a> from <aclass="reference"href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.