mirror of
https://github.com/boostorg/parameter.git
synced 2026-01-20 16:52:13 +00:00
1190 lines
68 KiB
HTML
Executable File
1190 lines
68 KiB
HTML
Executable File
<?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">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content="Docutils 0.3.8: http://docutils.sourceforge.net/" />
|
|
<title>The Boost Parameter Library</title>
|
|
<link rel="stylesheet" href="rst.css" type="text/css" />
|
|
</head>
|
|
<body>
|
|
<div class="document" id="the-boost-parameter-library">
|
|
<h1 class="title">The Boost Parameter Library</h1>
|
|
<p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p>
|
|
<hr class="docutils" />
|
|
<table class="docutils field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Abstract:</th><td class="field-body"><p class="first">Use this library to write functions that accept
|
|
arguments by name:</p>
|
|
<pre class="literal-block">
|
|
new_window("alert", <strong>width=10</strong>, <strong>titlebar=false</strong>);
|
|
</pre>
|
|
<p class="last">Since named arguments can be passed in any order, they are
|
|
especially useful when a function has more than one parameter
|
|
with a useful default value.</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr class="docutils" />
|
|
<table class="docutils field-list" frame="void" rules="none">
|
|
<col class="field-name" />
|
|
<col class="field-body" />
|
|
<tbody valign="top">
|
|
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Daniel Wallin</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:dalwan01@student.umu.se">dalwan01@student.umu.se</a></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Organization:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a></td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Date:</th><td class="field-body">$Date: 2005/07/18 20:34:31 $</td>
|
|
</tr>
|
|
<tr class="field"><th class="field-name">Copyright:</th><td class="field-body">Copyright David Abrahams, Daniel Wallin
|
|
2005. Distributed under the Boost Software License,
|
|
Version 1.0. (See accompanying file LICENSE_1_0.txt
|
|
or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr class="docutils" />
|
|
<div class="contents topic" id="table-of-contents">
|
|
<p class="topic-title first"><a name="table-of-contents"><strong>Table of Contents</strong></a></p>
|
|
<ul class="auto-toc simple">
|
|
<li><a class="reference" href="#introduction" id="id20" name="id20">1 Introduction</a></li>
|
|
<li><a class="reference" href="#tutorial" id="id21" name="id21">2 Tutorial</a><ul class="auto-toc">
|
|
<li><a class="reference" href="#headers-and-namespaces" id="id22" name="id22">2.1 Headers And Namespaces</a></li>
|
|
<li><a class="reference" href="#the-abstract-interface-to-dfs" id="id23" name="id23">2.2 The Abstract Interface to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt></a></li>
|
|
<li><a class="reference" href="#defining-the-keywords" id="id24" name="id24">2.3 Defining the Keywords</a></li>
|
|
<li><a class="reference" href="#defining-the-implementation-function" id="id25" name="id25">2.4 Defining the Implementation Function</a></li>
|
|
<li><a class="reference" href="#adding-defaults" id="id26" name="id26">2.5 Adding Defaults</a><ul class="auto-toc">
|
|
<li><a class="reference" href="#syntax" id="id27" name="id27">2.5.1 Syntax</a></li>
|
|
<li><a class="reference" href="#getting-more-realistic" id="id28" name="id28">2.5.2 Getting More Realistic</a></li>
|
|
<li><a class="reference" href="#the-binding-metafunction" id="id29" name="id29">2.5.3 The <tt class="docutils literal"><span class="pre">binding</span></tt> <span class="concept">Metafunction</span></a></li>
|
|
<li><a class="reference" href="#beyond-ordinary-default-arguments" id="id30" name="id30">2.5.4 Beyond Ordinary Default Arguments</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference" href="#syntactic-refinement" id="id31" name="id31">2.6 Syntactic Refinement</a><ul class="auto-toc">
|
|
<li><a class="reference" href="#describing-the-positional-argument-order" id="id32" name="id32">2.6.1 Describing the Positional Argument Order</a></li>
|
|
<li><a class="reference" href="#forwarding-functions" id="id33" name="id33">2.6.2 Forwarding Functions</a></li>
|
|
<li><a class="reference" href="#out-parameters" id="id34" name="id34">2.6.3 “Out” Parameters</a></li>
|
|
<li><a class="reference" href="#generating-forwarding-functions-with-macros" id="id35" name="id35">2.6.4 Generating Forwarding Functions with Macros</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference" href="#controlling-overload-resolution" id="id36" name="id36">2.7 Controlling Overload Resolution</a><ul class="auto-toc">
|
|
<li><a class="reference" href="#updating-the-parameterspec" id="id37" name="id37">2.7.1 Updating the <span class="concept">ParameterSpec</span></a></li>
|
|
<li><a class="reference" href="#applying-sfinae-to-the-overload-set" id="id38" name="id38">2.7.2 Applying SFINAE to the Overload Set</a></li>
|
|
<li><a class="reference" href="#reducing-boilerplate-with-macros" id="id39" name="id39">2.7.3 Reducing Boilerplate With Macros</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference" href="#efficiency-issues" id="id40" name="id40">2.8 Efficiency Issues</a><ul class="auto-toc">
|
|
<li><a class="reference" href="#eliminating-copies" id="id41" name="id41">2.8.1 Eliminating Copies</a></li>
|
|
<li><a class="reference" href="#lazy-default-computation" id="id42" name="id42">2.8.2 Lazy Default Computation</a></li>
|
|
<li><a class="reference" href="#default-forwarding" id="id43" name="id43">2.8.3 Default Forwarding</a></li>
|
|
<li><a class="reference" href="#dispatching-based-on-the-presence-of-a-default" id="id44" name="id44">2.8.4 Dispatching Based on the Presence of a Default</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference" href="#portability-considerations" id="id45" name="id45">3 Portability Considerations</a><ul class="auto-toc">
|
|
<li><a class="reference" href="#no-sfinae-support" id="id46" name="id46">3.1 No SFINAE Support</a></li>
|
|
<li><a class="reference" href="#no-support-for-result-of" id="id47" name="id47">3.2 No Support for <tt class="docutils literal"><span class="pre">result_of</span></tt></a></li>
|
|
<li><a class="reference" href="#can-t-declare-parameterspec-via-typedef" id="id48" name="id48">3.3 Can't Declare <span class="concept">ParameterSpec</span> via <tt class="docutils literal"><span class="pre">typedef</span></tt></a></li>
|
|
<li><a class="reference" href="#default-arguments-unsupported-on-nested-templates" id="id49" name="id49">3.4 Default Arguments Unsupported on Nested Templates</a></li>
|
|
<li><a class="reference" href="#compiler-can-t-see-references-in-unnamed-namespace" id="id50" name="id50">3.5 Compiler Can't See References In Unnamed Namespace</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference" href="#reference" id="id51" name="id51">4 Reference</a></li>
|
|
<li><a class="reference" href="#acknowledgements" id="id52" name="id52">5 Acknowledgements</a></li>
|
|
</ul>
|
|
</div>
|
|
<hr class="docutils" />
|
|
<div class="section" id="introduction">
|
|
<h1><a class="toc-backref" href="#id20" name="introduction">1 Introduction</a></h1>
|
|
<p>In C++, arguments are normally given meaning by their positions
|
|
with respect to a parameter list. That protocol is fine when there
|
|
is at most one parameter with a default value, but when there are
|
|
even a few useful defaults, the positional interface becomes
|
|
burdensome:</p>
|
|
<ul>
|
|
<li><p class="first">Since an argument's meaning is given by its position, we have to
|
|
choose an (often arbitrary) order for parameters with default
|
|
values, making some combinations of defaults unusable:</p>
|
|
<pre class="literal-block">
|
|
window* new_window(
|
|
char const* name,
|
|
<strong>int border_width = default_border_width,</strong>
|
|
bool movable = true,
|
|
bool initially_visible = true
|
|
);
|
|
|
|
const bool movability = false;
|
|
window* w = new_window("alert box", movability);
|
|
</pre>
|
|
<p>In the example above we wanted to make an unmoveable window
|
|
with a default <tt class="docutils literal"><span class="pre">border_width</span></tt>, but instead we got a moveable
|
|
window with a <tt class="docutils literal"><span class="pre">border_width</span></tt> of zero. To get the desired
|
|
effect, we'd need to write:</p>
|
|
<pre class="literal-block">
|
|
window* w = new_window(
|
|
"alert box", <strong>default_border_width</strong>, movability);
|
|
</pre>
|
|
</li>
|
|
<li><p class="first">It can become difficult for readers to understand the meaning of
|
|
arguments at the call site:</p>
|
|
<pre class="literal-block">
|
|
window* w = new_window("alert", 1, true, false);
|
|
</pre>
|
|
<p>Is this window moveable and initially invisible, or unmoveable
|
|
and initially visible? The reader needs to remember the order
|
|
of arguments to be sure.</p>
|
|
</li>
|
|
<li><p class="first">The author of the call may not remember the order of the
|
|
arguments either, leading to hard-to-find bugs.</p>
|
|
</li>
|
|
</ul>
|
|
<p>This library addresses the problems outlined above by associating
|
|
each parameter with a keyword object. Now users can identify
|
|
arguments by keyword, rather than by position:</p>
|
|
<pre class="literal-block">
|
|
window* w = new_window("alert box", <strong>movable=</strong>false); // OK!
|
|
</pre>
|
|
<!-- I'm inclined to leave this part out. In particular, the 2nd
|
|
point is kinda lame because even with the library, we need to
|
|
introduce overloads - - dwa:
|
|
|
|
C++ has two other limitations, with respect to default arguments,
|
|
that are unrelated to its positional interface:
|
|
|
|
* Default values cannot depend on the values of other function
|
|
parameters:
|
|
|
|
.. parsed-literal::
|
|
|
|
// Can we make resize windows to a square shape by default?
|
|
void resize(
|
|
window* w,
|
|
int **width**,
|
|
int height **= width** // nope, error!
|
|
);
|
|
|
|
* Default values in function templates are useless for any
|
|
argument whose type should be deduced when the argument is
|
|
supplied explicitly::
|
|
|
|
template <class T>
|
|
void f(T x = 0);
|
|
|
|
f(3.14) // ok: x supplied explicitly; T is double
|
|
f(); // error: can't deduce T from default argument 0!
|
|
|
|
As a side effect of using the Boost Parameter library, you may find
|
|
that you circumvent both of these limitations quite naturally. -->
|
|
</div>
|
|
<div class="section" id="tutorial">
|
|
<h1><a class="toc-backref" href="#id21" name="tutorial">2 Tutorial</a></h1>
|
|
<p>In this section we'll show how the Parameter library can be used to
|
|
build an expressive interface to the <a class="reference" href="../../../graph/index.html">Boost Graph library</a>'s
|
|
<a class="reference" href="../../../graph/doc/depth_first_search.html"><tt class="docutils literal"><span class="pre">depth_first_search</span></tt></a> algorithm.<a class="footnote-reference" href="#old-interface" id="id2" name="id2"><sup>1</sup></a> After laying some groundwork
|
|
and describing the algorithm's abstract interface, we'll show you
|
|
how to build a basic implementation with keyword support. Then
|
|
we'll add support for default arguments and we'll gradually refine the
|
|
implementation with syntax improvements. Finally we'll show how to
|
|
streamline the implementation of named parameter interfaces,
|
|
improve their participation in overload resolution, and optimize
|
|
their runtime efficiency.</p>
|
|
<div class="section" id="headers-and-namespaces">
|
|
<h2><a class="toc-backref" href="#id22" name="headers-and-namespaces">2.1 Headers And Namespaces</a></h2>
|
|
<p>Most components of the Parameter library are declared in a
|
|
header named for the component. For example,</p>
|
|
<pre class="literal-block">
|
|
#include <boost/parameter/keyword.hpp>
|
|
</pre>
|
|
<p>will ensure <tt class="docutils literal"><span class="pre">boost::parameter::keyword</span></tt> is known to the
|
|
compiler. There is also a combined header,
|
|
<tt class="docutils literal"><span class="pre">boost/parameter.hpp</span></tt>, that includes most of the library's
|
|
components. For the the rest of this tutorial, unless we say
|
|
otherwise, you can use the rule above to figure out which header
|
|
to <tt class="docutils literal"><span class="pre">#include</span></tt> to access any given component of the library.</p>
|
|
<p>Also, the examples below will also be written as if the
|
|
namespace alias</p>
|
|
<pre class="literal-block">
|
|
namespace parameter = boost::parameter;
|
|
</pre>
|
|
<p>has been declared: we'll write <tt class="docutils literal"><span class="pre">parameter::xxx</span></tt> instead of
|
|
<tt class="docutils literal"><span class="pre">boost::parameter::xxx</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="the-abstract-interface-to-dfs">
|
|
<h2><a class="toc-backref" href="#id23" name="the-abstract-interface-to-dfs">2.2 The Abstract Interface to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt></a></h2>
|
|
<p>The Graph library's <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> algorithm is a generic function accepting
|
|
from one to four arguments by reference. If all arguments were
|
|
required, its signature might be as follows:</p>
|
|
<pre class="literal-block">
|
|
template <
|
|
class Graph, class DFSVisitor, class Index, class ColorMap
|
|
>
|
|
void depth_first_search(
|
|
, Graph const& graph
|
|
, DFSVisitor visitor
|
|
, typename graph_traits<g>::vertex_descriptor root_vertex
|
|
, IndexMap index_map
|
|
, ColorMap& color);
|
|
</pre>
|
|
<p>However, most of the parameters have a useful default value, as
|
|
shown in the table below.</p>
|
|
<span class="target" id="parameter-table"></span><span class="target" id="default-expressions"></span><table border="1" class="docutils">
|
|
<caption><tt class="docutils literal"><span class="pre">depth_first_search</span></tt> Parameters</caption>
|
|
<colgroup>
|
|
<col width="27%" />
|
|
<col width="17%" />
|
|
<col width="57%" />
|
|
</colgroup>
|
|
<thead valign="bottom">
|
|
<tr><th>Parameter Name</th>
|
|
<th>Dataflow</th>
|
|
<th>Default Value (if any)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody valign="top">
|
|
<tr><td><tt class="docutils literal"><span class="pre">graph</span></tt></td>
|
|
<td>in</td>
|
|
<td>none - this argument is required.</td>
|
|
</tr>
|
|
<tr><td><tt class="docutils literal"><span class="pre">visitor</span></tt></td>
|
|
<td>in</td>
|
|
<td><tt class="docutils literal"><span class="pre">boost::dfs_visitor<>()</span></tt></td>
|
|
</tr>
|
|
<tr><td><tt class="docutils literal"><span class="pre">root_vertex</span></tt></td>
|
|
<td>in</td>
|
|
<td><tt class="docutils literal"><span class="pre">*vertices(graph).first</span></tt></td>
|
|
</tr>
|
|
<tr><td><tt class="docutils literal"><span class="pre">index_map</span></tt></td>
|
|
<td>in</td>
|
|
<td><tt class="docutils literal"><span class="pre">get(boost::vertex_index,graph)</span></tt></td>
|
|
</tr>
|
|
<tr><td><tt class="docutils literal"><span class="pre">color_map</span></tt></td>
|
|
<td>out</td>
|
|
<td>an <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt>
|
|
created from a <tt class="docutils literal"><span class="pre">std::vector</span></tt> of
|
|
<tt class="docutils literal"><span class="pre">default_color_type</span></tt> of size
|
|
<tt class="docutils literal"><span class="pre">num_vertices(graph)</span></tt> and using
|
|
<tt class="docutils literal"><span class="pre">index_map</span></tt> for the index map.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>Don't be intimidated by the complex default values. For the
|
|
purposes of this exercise, you don't need to understand what they
|
|
mean. Also, we'll show you how the default for <tt class="docutils literal"><span class="pre">color_map</span></tt> is
|
|
computed later in the tutorial; trust us when we say that the
|
|
complexity of its default will become valuable.</p>
|
|
</div>
|
|
<div class="section" id="defining-the-keywords">
|
|
<h2><a class="toc-backref" href="#id24" name="defining-the-keywords">2.3 Defining the Keywords</a></h2>
|
|
<p>The point of this exercise is to make it possible to call
|
|
<tt class="docutils literal"><span class="pre">depth_first_search</span></tt> with keyword arguments, leaving out any
|
|
arguments for which the default is appropriate:</p>
|
|
<pre class="literal-block">
|
|
graphs::depth_first_search(g, <strong>color_map = my_color_map</strong>);
|
|
</pre>
|
|
<p>To make that syntax legal, there needs to be an object called
|
|
<tt class="docutils literal"><span class="pre">color_map</span></tt> with an assignment operator that can accept a
|
|
<tt class="docutils literal"><span class="pre">my_color_map</span></tt> argument. In this step we'll create one such
|
|
<strong>keyword object</strong> for each parameter. Each keyword object will be
|
|
identified by a unique <strong>keyword tag type</strong>.</p>
|
|
<p>We're going to define our interface in namespace <tt class="docutils literal"><span class="pre">graphs</span></tt>. Since
|
|
users need access to the keyword objects, but not the tag types,
|
|
we'll define the keyword objects so they're acceessible through
|
|
<tt class="docutils literal"><span class="pre">graphs</span></tt>, and we'll hide the tag types away in a tested
|
|
namespace, <tt class="docutils literal"><span class="pre">graphs::tag</span></tt>. The library provides a convenient
|
|
macro for that purpose (MSVC6.x users see this <a class="reference" href="#compiler-can-t-see-references-in-unnamed-namespace">note</a>):</p>
|
|
<pre class="literal-block">
|
|
#include <boost/parameter/keyword.hpp>
|
|
|
|
namespace graphs
|
|
{
|
|
BOOST_PARAMETER_KEYWORD(tag, graph) // Note: no semicolon
|
|
BOOST_PARAMETER_KEYWORD(tag, visitor)
|
|
BOOST_PARAMETER_KEYWORD(tag, root_vertex)
|
|
BOOST_PARAMETER_KEYWORD(tag, index_map)
|
|
BOOST_PARAMETER_KEYWORD(tag, color_map)
|
|
}
|
|
</pre>
|
|
<p>The declaration of the <tt class="docutils literal"><span class="pre">visitor</span></tt> keyword you see here is
|
|
equivalent to:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs
|
|
{
|
|
namespace tag { struct visitor; }
|
|
namespace {
|
|
boost::parameter::keyword<tag::visitor>& visitor
|
|
= boost::parameter::keyword<tag::visitor>::get();
|
|
}
|
|
}
|
|
</pre>
|
|
<p>This “fancy dance” involving the unnamed namespace and references
|
|
is all done to avoid violating the One Definition Rule (ODR)<a class="footnote-reference" href="#odr" id="id5" name="id5"><sup>2</sup></a> when the named parameter interface is used by function
|
|
templates that are instantiated in multiple translation
|
|
units.</p>
|
|
</div>
|
|
<div class="section" id="defining-the-implementation-function">
|
|
<h2><a class="toc-backref" href="#id25" name="defining-the-implementation-function">2.4 Defining the Implementation Function</a></h2>
|
|
<p>Next we can write the skeleton of the function that implements
|
|
the core of <tt class="docutils literal"><span class="pre">depth_first_search</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs { namespace core
|
|
{
|
|
template <class ArgumentPack>
|
|
void depth_first_search(ArgumentPack const& args)
|
|
{
|
|
// algorithm implementation goes here
|
|
}
|
|
}}
|
|
</pre>
|
|
<p><tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt> has an <span class="concept">ArgumentPack</span>
|
|
parameter: a bundle of references to the arguments that the caller
|
|
passes to the algorithm, tagged with their keywords. To extract
|
|
each parameter, just pass its keyword object to the
|
|
<span class="concept">ArgumentPack</span>'s subscript operator. Just to get a feel for how
|
|
things work, let's add some temporary code to print the arguments:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs { namespace core
|
|
{
|
|
template <class ArgumentPack>
|
|
void depth_first_search(ArgumentPack const& args)
|
|
{
|
|
std::cout << "graph:\t" << <strong>args[graph]</strong> << std::endl;
|
|
std::cout << "visitor:\t" << <strong>args[visitor]</strong> << std::endl;
|
|
std::cout << "root_vertex:\t" << <strong>args[root_vertex]</strong> << std::endl;
|
|
std::cout << "index_map:\t" << <strong>args[index_map]</strong> << std::endl;
|
|
std::cout << "color_map:\t" << <strong>args[color_map]</strong> << std::endl;
|
|
}
|
|
}} // graphs::core
|
|
</pre>
|
|
<p>It's unlikely that many of the arguments the caller will eventually
|
|
pass to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> can be printed, but for now the code
|
|
above will give us something to experiment with. To see the
|
|
keywords in action, we can write a little test driver:</p>
|
|
<pre class="literal-block">
|
|
int main()
|
|
{
|
|
using namespace graphs;
|
|
|
|
core::depth_first_search(<strong>(</strong>
|
|
graph = 'G', visitor = 2, root_vertex = 3.5,
|
|
index_map = "hello, world", color_map = false<strong>)</strong>);
|
|
}
|
|
</pre>
|
|
<p>An overloaded comma operator (<tt class="docutils literal"><span class="pre">operator,</span></tt>) combines the results
|
|
of assigning to each keyword object into a single <span class="concept">ArgumentPack</span>
|
|
object that gets passed on to <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>. The
|
|
extra set of parentheses you see in the example above are required:
|
|
without them, each assignment would be interpreted as a separate
|
|
function argument and the comma operator wouldn't take effect.
|
|
We'll show you how to get rid of the extra parentheses later in
|
|
this tutorial.</p>
|
|
<p>Of course, we can pass the arguments in any order:</p>
|
|
<pre class="literal-block">
|
|
int main()
|
|
{
|
|
using namespace graphs;
|
|
|
|
core::depth_first_search((
|
|
root_vertex = 3.5, graph = 'G', color_map = false,
|
|
index_map = "hello, world", visitor = 2));
|
|
}
|
|
</pre>
|
|
<p>either of the two programs above will print:</p>
|
|
<pre class="literal-block">
|
|
graph: G
|
|
visitor: 2
|
|
root_vertex: 3.5
|
|
index_map: hello, world
|
|
color_map: false
|
|
</pre>
|
|
</div>
|
|
<div class="section" id="adding-defaults">
|
|
<h2><a class="toc-backref" href="#id26" name="adding-defaults">2.5 Adding Defaults</a></h2>
|
|
<p>Currently, all the arguments to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> are
|
|
required. If any parameter can't be found, there will be a
|
|
compilation error where we try to extract it from the
|
|
<span class="concept">ArgumentPack</span> using the subscript operator. To make it
|
|
legal to omit an argument we need to give it a default value.</p>
|
|
<div class="section" id="syntax">
|
|
<h3><a class="toc-backref" href="#id27" name="syntax">2.5.1 Syntax</a></h3>
|
|
<p>We can make any of the parameters optional by following its keyword
|
|
with the <tt class="docutils literal"><span class="pre">|</span></tt> operator and the parameter's default value within
|
|
the square brackets. In the following example, we've given
|
|
<tt class="docutils literal"><span class="pre">root_vertex</span></tt> a default of <tt class="docutils literal"><span class="pre">42</span></tt> and <tt class="docutils literal"><span class="pre">color_map</span></tt> a default of
|
|
<tt class="docutils literal"><span class="pre">"hello,</span> <span class="pre">world"</span></tt>.</p>
|
|
<pre class="literal-block">
|
|
namespace graphs { namespace core
|
|
{
|
|
template <class ArgumentPack>
|
|
void depth_first_search(ArgumentPack const& args)
|
|
{
|
|
std::cout << "graph:\t" << args[graph] << std::endl;
|
|
std::cout << "visitor:\t" << args[visitor] << std::endl;
|
|
std::cout << "root_vertex:\t" << args[root_vertex<strong>|42</strong>] << std::endl;
|
|
std::cout << "index_map:\t" << args[index_map] << std::endl;
|
|
std::cout << "color_map:\t" << args[color_map<strong>|"hello, world"</strong>] << std::endl;
|
|
}
|
|
}} // graphs::core
|
|
</pre>
|
|
<p>Now we can invoke the function without supplying <tt class="docutils literal"><span class="pre">color_map</span></tt> or
|
|
<tt class="docutils literal"><span class="pre">root_vertex</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
core::depth_first_search((
|
|
graph = 'G', index_map = "index", visitor = 6));
|
|
</pre>
|
|
<p>The call above would print:</p>
|
|
<pre class="literal-block">
|
|
graph: G
|
|
visitor: 6
|
|
root_vertex: 42
|
|
index_map: index
|
|
color_map: hello, world
|
|
</pre>
|
|
<div class="important">
|
|
<p class="first admonition-title">Important</p>
|
|
<p class="last">The index expression <tt class="docutils literal"><span class="pre">args[…]</span></tt> always yields a <em>reference</em>
|
|
that is bound either to the actual argument passed by the caller
|
|
or, if no argument is passed explicitly, to the specified
|
|
default value.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="getting-more-realistic">
|
|
<h3><a class="toc-backref" href="#id28" name="getting-more-realistic">2.5.2 Getting More Realistic</a></h3>
|
|
<p>Now it's time to put some more realistic defaults in place. We'll
|
|
have to give up our print statements—at least if we want to see the
|
|
defaults work—since, the default values of these
|
|
parameters generally aren't printable.</p>
|
|
<p>Instead, we'll connect local variables to the arguments and use
|
|
those in our algorithm:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs { namespace core
|
|
{
|
|
template <class ArgumentPack>
|
|
void depth_first_search(ArgumentPack const& args)
|
|
{
|
|
<em>Graph</em> g = args[graph];
|
|
<em>Visitor</em> v = args[visitor|<em>default-expression</em><sub>1</sub>];
|
|
<em>Vertex</em> s = args[root_vertex|<em>default-expression</em><sub>2</sub>];
|
|
<em>Index</em> i = args[index_map|<em>default-expression</em><sub>3</sub>];
|
|
<em>Color</em> c = args[visitor|<em>default-expression</em><sub>4</sub>];
|
|
|
|
<em>…use g, v, s, i, and c to implement the algorithm…</em>
|
|
}
|
|
}} // graphs::core
|
|
</pre>
|
|
<p>We'll insert the <a class="reference" href="#default-expressions">default expressions</a> in a moment, but first we
|
|
need to come up with the types <em>Graph</em>, <em>Visitor</em>, <em>Vertex</em>,
|
|
<em>Index</em>, and <em>Color</em>.</p>
|
|
</div>
|
|
<div class="section" id="the-binding-metafunction">
|
|
<h3><a name="the-binding-metafunction">2.5.3 The <tt class="docutils literal"><span class="pre">binding</span></tt> <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a></a></h3>
|
|
<p>To compute the type of a parameter we can use a <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a>
|
|
called <tt class="docutils literal"><span class="pre">binding</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
binding<ArgumentPack, Keyword, Default = void>
|
|
{ typedef <em>see text</em> type; };
|
|
</pre>
|
|
<p>where <tt class="docutils literal"><span class="pre">Default</span></tt> is the type of the default argument, if any.</p>
|
|
<p>For example, to declare and initialize <tt class="docutils literal"><span class="pre">g</span></tt> above, we could write:</p>
|
|
<pre class="literal-block">
|
|
typedef typename parameter::binding<
|
|
ArgumentPack,<strong>tag::graph</strong>
|
|
>::type Graph;
|
|
|
|
Graph g = args[graph];
|
|
</pre>
|
|
<p>As shown in the <a class="reference" href="#parameter-table">parameter table</a>, <tt class="docutils literal"><span class="pre">graph</span></tt> has no default, so
|
|
the <tt class="docutils literal"><span class="pre">binding</span></tt> invocation for <em>Graph</em> takes only two arguments.
|
|
The default <tt class="docutils literal"><span class="pre">visitor</span></tt> is <tt class="docutils literal"><span class="pre">boost::dfs_visitor<>()</span></tt>, so the
|
|
<tt class="docutils literal"><span class="pre">binding</span></tt> invocation for <em>Visitor</em> takes three arguments:</p>
|
|
<pre class="literal-block">
|
|
typedef typename parameter::binding<
|
|
ArgumentPack,<strong>tag::visitor,boost::dfs_visitor<></strong>
|
|
>::type Visitor;
|
|
|
|
Visitor v = args[visitor|<strong>boost::dfs_visitor<>()</strong>];
|
|
</pre>
|
|
<p>Note that the default <tt class="docutils literal"><span class="pre">visitor</span></tt> is supplied as a <em>temporary</em>
|
|
instance of <tt class="docutils literal"><span class="pre">dfs_visitor</span></tt>. Because <tt class="docutils literal"><span class="pre">args[…]</span></tt> always yields
|
|
a reference, making <tt class="docutils literal"><span class="pre">v</span></tt> a reference would cause it to bind to
|
|
that temporary, and immediately dangle. Therefore, it's crucial
|
|
that we passed <tt class="docutils literal"><span class="pre">dfs_visitor<></span></tt>, and not <tt class="docutils literal"><span class="pre">dfs_visitor<></span>
|
|
<span class="pre">const&</span></tt>, as the last argument to <tt class="docutils literal"><span class="pre">binding</span></tt>.</p>
|
|
<div class="important">
|
|
<p class="first admonition-title">Important</p>
|
|
<p class="last">Never pass <tt class="docutils literal"><span class="pre">binding</span></tt> a reference type as the default unless
|
|
you know that the default value passed to the <span class="concept">ArgumentPack</span>'s
|
|
indexing operator will outlive the reference you'll bind to it.</p>
|
|
</div>
|
|
<p>Sometimes there's no need to use <tt class="docutils literal"><span class="pre">binding</span></tt> at all. The
|
|
<tt class="docutils literal"><span class="pre">root_vertex</span></tt> argument is required to be of the graph's
|
|
<tt class="docutils literal"><span class="pre">vertex_descriptor</span></tt> type,<a class="footnote-reference" href="#vertex-descriptor" id="id6" name="id6"><sup>3</sup></a> so we can just
|
|
use that knowledge to bypass <tt class="docutils literal"><span class="pre">binding</span></tt> altogether.</p>
|
|
<pre class="literal-block">
|
|
typename <strong>boost::graph_traits<Graph>::vertex_descriptor</strong>
|
|
s = args[root_vertex|<strong>*vertices(g).first</strong>];
|
|
</pre>
|
|
<span class="target" id="dangling"></span></div>
|
|
<div class="section" id="beyond-ordinary-default-arguments">
|
|
<h3><a class="toc-backref" href="#id30" name="beyond-ordinary-default-arguments">2.5.4 Beyond Ordinary Default Arguments</a></h3>
|
|
<p>Here's how you might write the declaration for the <tt class="docutils literal"><span class="pre">index_map</span></tt>
|
|
parameter:</p>
|
|
<pre class="literal-block">
|
|
typedef typename parameter::binding<
|
|
ArgumentPack
|
|
, tag::index_map
|
|
, <strong>typename boost::property_map<Graph, vertex_index_t>::const_type</strong>
|
|
>::type Index;
|
|
|
|
Index i = args[index_map|<strong>get(boost::vertex_index,g)</strong>];
|
|
</pre>
|
|
<p>Notice two capabilities we've gained over what
|
|
plain C++ default arguments provide:</p>
|
|
<ol class="arabic">
|
|
<li><p class="first">The default value of the <tt class="docutils literal"><span class="pre">index</span></tt> parameter depends on the
|
|
value of the <tt class="docutils literal"><span class="pre">graph</span></tt> parameter. That's illegal in plain C++:</p>
|
|
<pre class="literal-block">
|
|
void f(int <strong>graph</strong>, int index = <strong>graph</strong> + 1); // error
|
|
</pre>
|
|
</li>
|
|
<li><p class="first">The <tt class="docutils literal"><span class="pre">index</span></tt> parameter has a useful default, yet it is
|
|
templated and its type can be deduced when an <tt class="docutils literal"><span class="pre">index</span></tt>
|
|
argument is explicitly specified by the caller. In plain C++, you
|
|
can <em>specify</em> a default value for a parameter with deduced type,
|
|
but it's not very useful:</p>
|
|
<pre class="literal-block">
|
|
template <class Index>
|
|
int f(Index index <strong>= 42</strong>); // OK
|
|
int y = f(); // <strong>error; can't deduce Index</strong>
|
|
</pre>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="syntactic-refinement">
|
|
<h2><a class="toc-backref" href="#id31" name="syntactic-refinement">2.6 Syntactic Refinement</a></h2>
|
|
<p>In this section we'll describe how you can allow callers to invoke
|
|
<tt class="docutils literal"><span class="pre">depth_first_search</span></tt> with just one pair of parentheses, and to
|
|
omit keywords where appropriate.</p>
|
|
<div class="section" id="describing-the-positional-argument-order">
|
|
<h3><a class="toc-backref" href="#id32" name="describing-the-positional-argument-order">2.6.1 Describing the Positional Argument Order</a></h3>
|
|
<span class="target" id="parameterspec"></span><p>First, we'll need to build a type that describes the allowed
|
|
parameters and their ordering when passed positionally. This type
|
|
is known as a <span class="concept">ParameterSpec</span> (MSVC6.x users see this <a class="reference" href="#can-t-declare-parameterspec-via-typedef">note</a>):</p>
|
|
<pre class="literal-block">
|
|
namespace graphs
|
|
{
|
|
typedef parameter::parameters<
|
|
tag::graph
|
|
, tag::visitor
|
|
, tag::root_vertex
|
|
, tag::index_map
|
|
, tag::color_map
|
|
> dfs_params;
|
|
}
|
|
</pre>
|
|
<p>The <tt class="docutils literal"><span class="pre">parameters</span></tt> template supplies a function-call
|
|
operator that groups all its arguments into an <span class="concept">ArgumentPack</span>. Any
|
|
arguments passed to it without a keyword label will be associated
|
|
with a parameter according to its position in the <span class="concept">ParameterSpec</span>.
|
|
So for example, given an object <tt class="docutils literal"><span class="pre">p</span></tt> of type <tt class="docutils literal"><span class="pre">dfs_params</span></tt>,</p>
|
|
<pre class="literal-block">
|
|
p('G', index_map=1)
|
|
</pre>
|
|
<p>yields an <span class="concept">ArgumentPack</span> whose <tt class="docutils literal"><span class="pre">graph</span></tt> parameter has a value of
|
|
<tt class="docutils literal"><span class="pre">'G'</span></tt>, and whose <tt class="docutils literal"><span class="pre">index_map</span></tt> parameter has a value of <tt class="docutils literal"><span class="pre">1</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="forwarding-functions">
|
|
<h3><a class="toc-backref" href="#id33" name="forwarding-functions">2.6.2 Forwarding Functions</a></h3>
|
|
<p>Next we need a family of overloaded <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> function
|
|
templates that can be called with anywhere from one to five
|
|
arguments. These <em>forwarding functions</em> will invoke an instance of
|
|
<tt class="docutils literal"><span class="pre">dfs_params</span></tt> as a function object, passing their parameters
|
|
to its <tt class="docutils literal"><span class="pre">operator()</span></tt> and forwarding the result on to
|
|
<tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs
|
|
{
|
|
template <class A0>
|
|
void depth_first_search(A0 const& a0)
|
|
{
|
|
core::depth_first_search(dfs_params()(a0));
|
|
}
|
|
|
|
template <class A0, class A1>
|
|
void depth_first_search(A0 const& a0, A1 const& a1)
|
|
{
|
|
core::depth_first_search(dfs_params()(a0,a1));
|
|
}
|
|
<span class="doublesize">⋮</span>
|
|
template <class A0, class A1, …class A4>
|
|
void depth_first_search(A0 const& a0, A1 const& a1, …A4 const& a4)
|
|
{
|
|
core::depth_first_search(dfs_params()(a0,a1,a2,a3,a4));
|
|
}
|
|
}
|
|
</pre>
|
|
<p>That's it! We can now call <tt class="docutils literal"><span class="pre">graphs::depth_first_search</span></tt> with
|
|
from one to five arguments passed positionally or via keyword.</p>
|
|
</div>
|
|
<div class="section" id="out-parameters">
|
|
<h3><a class="toc-backref" href="#id34" name="out-parameters">2.6.3 “Out” Parameters</a></h3>
|
|
<p>Well, that's not <em>quite</em> it. When passing arguments by keyword,
|
|
the keyword object's assignment operator yields a temporary
|
|
<span class="concept">ArgumentPack</span> object. A conforming C++ compiler will refuse to
|
|
bind a non-<tt class="docutils literal"><span class="pre">const</span></tt> reference to a temporary, so to support a
|
|
keyword interface for all arguments, the overload set above <em>must</em>
|
|
take its arguments by <tt class="docutils literal"><span class="pre">const</span></tt> reference. On the other hand—as
|
|
you may recall from the <a class="reference" href="#parameter-table">parameter table</a>—<tt class="docutils literal"><span class="pre">color_map</span></tt> is an
|
|
“out” parameter, so it really should be passed by <em>non-</em><tt class="docutils literal"><span class="pre">const</span></tt>
|
|
reference.</p>
|
|
<p>A keyword object has a pair of <tt class="docutils literal"><span class="pre">operator=</span></tt> overloads that ensure
|
|
we can pass anything—temporary or not, <tt class="docutils literal"><span class="pre">const</span></tt> or not—by name,
|
|
while preserving the mutability of non-temporaries:</p>
|
|
<pre class="literal-block">
|
|
template <class A> // handles non-const,
|
|
<span class="concept">ArgumentPack</span> operator=(A&); // non-temporary objects
|
|
|
|
template <class A> // handles const objects
|
|
<span class="concept">ArgumentPack</span> operator=(A const&); // and temporaries
|
|
</pre>
|
|
<p>However, when an “out” parameter is passed positionally, there's no
|
|
keyword object involved. With our <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> overload
|
|
set above, the <tt class="docutils literal"><span class="pre">color_map</span></tt> will be passed by <tt class="docutils literal"><span class="pre">const</span></tt> reference,
|
|
and compilation will fail when mutating operations are used on it.
|
|
The simple solution is to add another overload that takes a
|
|
non-<tt class="docutils literal"><span class="pre">const</span></tt> reference in the position of the “out” parameter:</p>
|
|
<pre class="literal-block">
|
|
template <class A0, class A1, …class A4>
|
|
void depth_first_search(A0 <strong>const&</strong> a0, A1 <strong>const&</strong> a1, …A4<strong>&</strong> a4)
|
|
{
|
|
core::depth_first_search(dfs_params()(a0,a1,a2,a3,a4));
|
|
}
|
|
</pre>
|
|
<p>That approach works nicely because there is only one “out”
|
|
parameter and it is in the last position. If <tt class="docutils literal"><span class="pre">color_map</span></tt> had
|
|
been the first parameter, we would have needed <em>ten</em> overloads. In
|
|
the worst case—where the function has five “out” parameters—2<sup>5</sup> or 32 overloads would be required. This “<a class="reference" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">forwarding
|
|
problem</a>” is well-known to generic library authors, and the C++
|
|
standard committee is working on a <a class="reference" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">proposal</a> to address it. In
|
|
the meantime, you might consider using <a class="reference" href="../../../preprocessor">Boost.Preprocessor</a> to
|
|
generate the overloads you need.</p>
|
|
<p>If it is impractical for you to generate or write the overloads
|
|
that would be required for positional “out” arguments to be passed
|
|
directly, you still have the option to ask users to pass them
|
|
through <a class="reference" href="http://www.boost.org/doc/html/reference_wrapper.html"><tt class="docutils literal"><span class="pre">boost::ref</span></tt></a>, which will ensure that the algorithm implementation
|
|
sees a non-<tt class="docutils literal"><span class="pre">const</span></tt> reference:</p>
|
|
<pre class="literal-block">
|
|
depth_first_search(g, v, s, i, <strong>boost::ref(c)</strong>);
|
|
</pre>
|
|
</div>
|
|
<div class="section" id="generating-forwarding-functions-with-macros">
|
|
<h3><a class="toc-backref" href="#id35" name="generating-forwarding-functions-with-macros">2.6.4 Generating Forwarding Functions with Macros</a></h3>
|
|
<p>To remove some of the tedium of writing overloaded forwarding
|
|
functions, the library supplies a macro, suitably located in
|
|
<tt class="docutils literal"><span class="pre">boost/parameter/macros.hpp</span></tt>, that will generate free function
|
|
overloads for you:</p>
|
|
<pre class="literal-block">
|
|
BOOST_PARAMETER_FUN(void, depth_first_search, 1, 5, dfs_params);
|
|
</pre>
|
|
<p>will generate a family of five <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> overloads, in
|
|
the current scope, that pass their arguments through
|
|
<tt class="docutils literal"><span class="pre">dfs_params</span></tt>. Instead of <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>, these
|
|
overloads will forward the <span class="concept">ArgumentPack</span> on to a function called
|
|
<tt class="docutils literal"><span class="pre">depth_first_search_with_named_params</span></tt>, also in the current
|
|
scope. It's up to you to implement that function. You could
|
|
simply transplant the body of <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt> into
|
|
<tt class="docutils literal"><span class="pre">depth_first_search_with_named_params</span></tt> if you were going to use
|
|
this approach.</p>
|
|
<p>Note that <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN</span></tt> only takes arguments by <tt class="docutils literal"><span class="pre">const</span></tt>
|
|
reference, so you will have to add any additional overloads
|
|
required to handle positional “out” parameters yourself. We are
|
|
looking into providing a more sophisticated set of macros to
|
|
address this problem and others, for an upcoming release of Boost.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="controlling-overload-resolution">
|
|
<h2><a class="toc-backref" href="#id36" name="controlling-overload-resolution">2.7 Controlling Overload Resolution</a></h2>
|
|
<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 <a class="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<a class="footnote-reference" href="#using" id="id9" name="id9"><sup>5</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 remove the functions
|
|
from the overload set when the passed argument types aren't
|
|
appropriate.</p>
|
|
<div class="section" id="updating-the-parameterspec">
|
|
<h3><a class="toc-backref" href="#id37" name="updating-the-parameterspec">2.7.1 Updating the <span class="concept">ParameterSpec</span></a></h3>
|
|
<p>This sort of overload control can be accomplished in C++ by taking
|
|
advantage of the SFINAE (Substitution Failure Is Not An Error)
|
|
rule.<a class="footnote-reference" href="#sfinae" id="id11" name="id11"><sup>6</sup></a> You can take advantage of the Parameter library's
|
|
built-in SFINAE support by using the following class templates in
|
|
your <span class="concept">ParameterSpec</span>:</p>
|
|
<pre class="literal-block">
|
|
template< class KeywordTag, class Predicate = <em>unspecified</em> >
|
|
struct required;
|
|
|
|
template< class KeywordTag, class Predicate = <em>unspecified</em> >
|
|
struct optional;
|
|
</pre>
|
|
<p>Instead of using keyword tags directly, we can wrap them in
|
|
<tt class="docutils literal"><span class="pre">required</span></tt> and <tt class="docutils literal"><span class="pre">optional</span></tt> to indicate which function parameters
|
|
are required, and optionally pass <tt class="docutils literal"><span class="pre">Predicate</span></tt>s to describe the
|
|
type requirements for each function parameter. The <tt class="docutils literal"><span class="pre">Predicate</span></tt>
|
|
argument must be a unary <a class="reference" href="../../../mpl/doc/refmanual/lambda-expression.html">MPL lambda expression</a> that, when
|
|
applied to the actual type of 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 <tt class="docutils literal"><span class="pre">depth_first_search()</span></tt> so that
|
|
the <tt class="docutils literal"><span class="pre">graph</span></tt> parameter is required and the <tt class="docutils literal"><span class="pre">root_vertex</span></tt>
|
|
parameter is convertible to <tt class="docutils literal"><span class="pre">int</span></tt>. We might write:</p>
|
|
<pre class="literal-block">
|
|
#include <boost/type_traits/is_convertible.hpp>
|
|
#include <boost/mpl/placeholders.hpp>
|
|
namespace graphs
|
|
{
|
|
using namespace boost::mpl::placeholders;
|
|
|
|
struct dfs_params
|
|
: parameter::parameters<
|
|
<strong>parameter::required<tag::graph></strong>
|
|
, parameter::optional<tag::visitor>
|
|
, <strong>parameter::optional<
|
|
tag::root_vertex, boost::is_convertible<_,int>
|
|
></strong>
|
|
, parameter::optional<tag::index_map>
|
|
, parameter::optional<tag::color_map>
|
|
>
|
|
{};
|
|
}
|
|
</pre>
|
|
</div>
|
|
<div class="section" id="applying-sfinae-to-the-overload-set">
|
|
<h3><a class="toc-backref" href="#id38" name="applying-sfinae-to-the-overload-set">2.7.2 Applying SFINAE to the Overload Set</a></h3>
|
|
<p>Now we add a special defaulted argument to each of our
|
|
<tt class="docutils literal"><span class="pre">depth_first_search</span></tt> overloads:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs
|
|
{
|
|
template <class A0>
|
|
void depth_first_search(
|
|
A0 const& a0
|
|
, typename dfs_params::match<A0>::type p = dfs_params())
|
|
{
|
|
core::depth_first_search(<strong>p</strong>(a0));
|
|
}
|
|
|
|
template <class A0, class A1>
|
|
void depth_first_search(
|
|
A0 const& a0, A1 const& a1
|
|
, typename dfs_params::match<A0,A1>::type p = dfs_params())
|
|
{
|
|
core::depth_first_search(<strong>p</strong>(a0,a1));
|
|
}
|
|
<span class="doublesize">⋮</span>
|
|
template <class A0, class A1, …class A4>
|
|
void depth_first_search(
|
|
A0 const& a0, A1 const& a1, …A4 const& A4
|
|
, typename dfs_params::match<A0,A1,A2,A3,A4>::type p = dfs_params())
|
|
{
|
|
core::depth_first_search(<strong>p</strong>(a0,a1,a2,a3,a4));
|
|
}
|
|
}
|
|
</pre>
|
|
<p>These additional parameters are not intended to be used directly
|
|
by callers; they merely trigger SFINAE by becoming illegal types
|
|
when the <tt class="docutils literal"><span class="pre">name</span></tt> argument is not convertible to <tt class="docutils literal"><span class="pre">const</span>
|
|
<span class="pre">char*</span></tt>. The <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN</span></tt> macro described earlier
|
|
adds these extra function parameters for you (Borland users see
|
|
this <a class="reference" href="#default-arguments-unsupported-on-nested-templates">note</a>).</p>
|
|
</div>
|
|
<div class="section" id="reducing-boilerplate-with-macros">
|
|
<h3><a class="toc-backref" href="#id39" name="reducing-boilerplate-with-macros">2.7.3 Reducing Boilerplate With Macros</a></h3>
|
|
<p>The library provides a macro you can use to eliminate some of the
|
|
repetetiveness of the declaring the optional parameters.
|
|
<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH</span></tt> takes three arguments: the
|
|
<span class="concept">ParameterSpec</span>, a <a class="reference" href="http://boost-consulting.com/mplbook/preprocessor.html#sequences">Boost.Preprocessor sequence</a> of the function
|
|
argument types, and a name for the defaulted function parameter
|
|
(<tt class="docutils literal"><span class="pre">p</span></tt>, above), and it generates the appropriate defaulted
|
|
argument. So we could shorten the overload set definition as
|
|
follows:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs
|
|
{
|
|
template <class A0>
|
|
void depth_first_search(
|
|
A0 const& a0
|
|
, <strong>BOOST_PARAMETER_MATCH(dfs_params, (A0), p)</strong>)
|
|
{
|
|
core::depth_first_search(p(a0));
|
|
}
|
|
|
|
template <class A0, class A1>
|
|
void depth_first_search(
|
|
A0 const& a0, A1 const& a1
|
|
, <strong>BOOST_PARAMETER_MATCH(dfs_params, (A0)(A1), p)</strong>)
|
|
{
|
|
core::depth_first_search(p(a0,a1));
|
|
}
|
|
<span class="doublesize">⋮</span>
|
|
template <class A0, class A1, …class A4>
|
|
void depth_first_search(
|
|
A0 const& a0, A1 const& a1, …A4 const& A4
|
|
, <strong>BOOST_PARAMETER_MATCH(dfs_params, (A0)(A1)…(A4), p)</strong>)
|
|
{
|
|
core::depth_first_search(p(a0,a1,a2,a3,a4));
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="efficiency-issues">
|
|
<h2><a class="toc-backref" href="#id40" name="efficiency-issues">2.8 Efficiency Issues</a></h2>
|
|
<p>The <tt class="docutils literal"><span class="pre">color_map</span></tt> parameter gives us a few efficiency issues to
|
|
consider. Here's a first cut at extraction and binding:</p>
|
|
<pre class="literal-block">
|
|
typedef
|
|
vector_property_map<boost::default_color_type, Index>
|
|
default_color_map;
|
|
|
|
typename parameter::binding<
|
|
ArgumentPack
|
|
, tag::color_map
|
|
, default_color_map
|
|
>::type color = args[color_map|<strong>default_color_map(num_vertices(g),i)</strong>];
|
|
</pre>
|
|
<div class="section" id="eliminating-copies">
|
|
<h3><a class="toc-backref" href="#id41" name="eliminating-copies">2.8.1 Eliminating Copies</a></h3>
|
|
<p>The library has no way to know whether an explicitly-supplied
|
|
argument is expensive to copy (or even if it is copyable at all),
|
|
so <tt class="docutils literal"><span class="pre">binding<…,k,…>::type</span></tt> is always a reference type when the
|
|
<em>k</em> parameter is supplied by the caller. Since <tt class="docutils literal"><span class="pre">args[…]</span></tt>
|
|
yields a reference to the actual argument, <tt class="docutils literal"><span class="pre">color</span></tt> will be bound
|
|
to the actual <tt class="docutils literal"><span class="pre">color_map</span></tt> argument and no copying will be done.</p>
|
|
<p>As described <a class="reference" href="#dangling">above</a>, because the default is a temporary, it's
|
|
important that <tt class="docutils literal"><span class="pre">color</span></tt> be a non-reference when the default is
|
|
used. In that case, the default value will be <em>copied</em> into
|
|
<tt class="docutils literal"><span class="pre">color</span></tt>. If we store the default in a named variable, though,
|
|
<tt class="docutils literal"><span class="pre">color</span></tt> can be a reference, thereby eliminating the copy:</p>
|
|
<pre class="literal-block">
|
|
default_color_map default_color(num_vertices(g),i);
|
|
|
|
typename parameter::binding<
|
|
ArgumentPack
|
|
, tag::color_map
|
|
, <strong>default_color_map&</strong>
|
|
>::type color = args[color_map|default_color];
|
|
</pre>
|
|
<div class="hint">
|
|
<p class="first admonition-title">Hint</p>
|
|
<p class="last">To avoid making needless copies, pass a <em>reference to the
|
|
default type</em> as the third argument to <tt class="docutils literal"><span class="pre">binding</span></tt>.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="lazy-default-computation">
|
|
<h3><a class="toc-backref" href="#id42" name="lazy-default-computation">2.8.2 Lazy Default Computation</a></h3>
|
|
<p>Of course it's nice to avoid copying <tt class="docutils literal"><span class="pre">default_color</span></tt>, but the
|
|
more important cost is that of <em>constructing</em> it in the first
|
|
place. A <tt class="docutils literal"><span class="pre">vector_property_map</span></tt> is cheap to copy, since it holds
|
|
its elements via a <a class="reference" href="../../../smart_ptr/shared_ptr.htm"><tt class="docutils literal"><span class="pre">shared_ptr</span></tt></a>. On the other hand, construction of
|
|
<tt class="docutils literal"><span class="pre">default_color</span></tt> costs at least two dynamic memory allocations and
|
|
<tt class="docutils literal"><span class="pre">num_vertices(g)</span></tt> copies; it would be better to avoid doing this
|
|
work when the default value won't be needed.</p>
|
|
<p>To that end, the library allows us to supply a callable object
|
|
that—if no argument was supplied by the caller—will be invoked to
|
|
construct the default value. Instead of following the keyword with
|
|
the <tt class="docutils literal"><span class="pre">|</span></tt> operator, we'll use <tt class="docutils literal"><span class="pre">||</span></tt> and follow it with a
|
|
nullary (zero-argument) function object that constructs a
|
|
default_color_map. Here, we build the function object using
|
|
<a class="reference" href="../../../lambda/index.html">Boost.Lambda</a>:<a class="footnote-reference" href="#bind" id="id15" name="id15"><sup>4</sup></a></p>
|
|
<pre class="literal-block">
|
|
// After #include <boost/lambda/construct.hpp>
|
|
typename parameter::binding<
|
|
ArgumentPack
|
|
, tag::color_map
|
|
, default_color_map
|
|
>::type color = args[
|
|
color_map
|
|
<strong>|| boost::lambda::construct<default_color_map>(num_vertices(g),i)</strong>
|
|
];
|
|
</pre>
|
|
<div class="sidebar">
|
|
<p class="first sidebar-title">Memnonics</p>
|
|
<p class="last">To remember the difference between <tt class="docutils literal"><span class="pre">|</span></tt> and <tt class="docutils literal"><span class="pre">||</span></tt>, recall that
|
|
<tt class="docutils literal"><span class="pre">||</span></tt> normally uses short-circuit evaluation: its second
|
|
argument is only evaluated if its first argument is <tt class="docutils literal"><span class="pre">false</span></tt>.
|
|
Similarly, in <tt class="docutils literal"><span class="pre">color_map[param||f]</span></tt>, <tt class="docutils literal"><span class="pre">f</span></tt> is only invoked if
|
|
no <tt class="docutils literal"><span class="pre">color_map</span></tt> argument was supplied.</p>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="default-forwarding">
|
|
<h3><a class="toc-backref" href="#id43" name="default-forwarding">2.8.3 Default Forwarding</a></h3>
|
|
<p>Types that are expensive to construct yet cheap to copy aren't all
|
|
that typical, and even copying the color map is more expensive than
|
|
we might like. It might be nice to avoid both needless
|
|
construction <em>and</em> needless copying of the default color map. The
|
|
simplest way to achieve that is to avoid naming it altogether, at
|
|
least not in <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>. Instead, we'll
|
|
introduce another function template to implement the actual
|
|
algorithm:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs { namespace core
|
|
{
|
|
template <class G, class V, class S, class I, class C>
|
|
void <strong>dfs_impl</strong>(G& g, V& v, S& s, I& i, C& c)
|
|
{
|
|
<em>…actual algorithm implementation…</em>
|
|
}
|
|
}}
|
|
</pre>
|
|
<p>Then, in <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>, we'll simply forward the
|
|
result of indexing <tt class="docutils literal"><span class="pre">args</span></tt> to <tt class="docutils literal"><span class="pre">core::dfs_impl</span></tt>:</p>
|
|
<pre class="literal-block">
|
|
core::dfs_impl(
|
|
g,v,s,i
|
|
, args[
|
|
color_map
|
|
|| boost::lambda::construct<default_color_map>(num_vertices(g),i)
|
|
]);
|
|
</pre>
|
|
<p>In real code, after going to the trouble to write <tt class="docutils literal"><span class="pre">dfs_impl</span></tt>,
|
|
we'd probably just forward all the arguments.</p>
|
|
</div>
|
|
<div class="section" id="dispatching-based-on-the-presence-of-a-default">
|
|
<h3><a class="toc-backref" href="#id44" name="dispatching-based-on-the-presence-of-a-default">2.8.4 Dispatching Based on the Presence of a Default</a></h3>
|
|
<p>In fact, the Graph library itself constructs a slightly different
|
|
<tt class="docutils literal"><span class="pre">color_map</span></tt>, to avoid even the overhead of initializing a
|
|
<a class="reference" href="../../../smart_ptr/shared_ptr.htm"><tt class="docutils literal"><span class="pre">shared_ptr</span></tt></a>:</p>
|
|
<pre class="literal-block">
|
|
std::vector<boost::default_color_type>
|
|
color_vec(num_vertices(g));
|
|
|
|
boost::iterator_property_map<
|
|
typename std::vector<
|
|
boost::default_color_type
|
|
>::iterator
|
|
, Index
|
|
> c(color_vec.begin(), i);
|
|
</pre>
|
|
<p>To avoid instantiating that code when it isn't needed, we'll have
|
|
to find a way to select different function implementations, at
|
|
compile time, based on whether a <tt class="docutils literal"><span class="pre">color_map</span></tt> argument was
|
|
supplied. By using <a class="reference" href="../../../../more/generic_programming.html#tag_dispatching">tag dispatching</a> on the presence of a
|
|
<tt class="docutils literal"><span class="pre">color_map</span></tt> argument, we can do just that:</p>
|
|
<pre class="literal-block">
|
|
#include <boost/type_traits/is_same.hpp>
|
|
#include <boost/mpl/bool.hpp>
|
|
|
|
namespace graphs { namespace core {
|
|
|
|
template <class ArgumentPack>
|
|
void dfs_dispatch(ArgumentPack& args, <strong>mpl::true_</strong>)
|
|
{
|
|
<em>…use the color map computed in the previous example…</em>
|
|
}
|
|
|
|
template <class ArgumentPack>
|
|
void dfs_dispatch(ArgumentPack& args, <strong>mpl::false_</strong>)
|
|
{
|
|
<em>…use args[color]…</em>
|
|
}
|
|
|
|
template <class ArgumentPack>
|
|
void depth_first_search(ArgumentPack& args)
|
|
{
|
|
typedef typename binding<args,tag::color>::type color_;
|
|
core::dfs_dispatch(args, <strong>boost::is_same<color_,void>()</strong>);
|
|
}
|
|
}}
|
|
</pre>
|
|
<p>We've used the fact that the default for <tt class="docutils literal"><span class="pre">binding</span></tt>'s third
|
|
argument is <tt class="docutils literal"><span class="pre">void</span></tt>: because specializations of <tt class="docutils literal"><span class="pre">is_same</span></tt> are
|
|
<tt class="docutils literal"><span class="pre">bool</span></tt>-valued MPL <a class="reference" href="../../../mpl/doc/refmanual/integral-constant.html"><span class="concept">Integral Constant</span></a>s derived either
|
|
from <tt class="docutils literal"><span class="pre">mpl::true_</span></tt> or <tt class="docutils literal"><span class="pre">mpl::false_</span></tt>, the appropriate
|
|
<tt class="docutils literal"><span class="pre">dfs_dispatch</span></tt> implementation will be selected.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="portability-considerations">
|
|
<h1><a class="toc-backref" href="#id45" name="portability-considerations">3 Portability Considerations</a></h1>
|
|
<p>Use the <a class="reference" href="http://www.boost.org/regression/release/user/parameter.html">regression test results</a> for the latest Boost release of
|
|
the Parameter library to see how it fares on your favorite
|
|
compiler. Additionally, you may need to be aware of the following
|
|
issues and workarounds for particular compilers.</p>
|
|
<div class="section" id="no-sfinae-support">
|
|
<h2><a class="toc-backref" href="#id46" name="no-sfinae-support">3.1 No SFINAE Support</a></h2>
|
|
<p>Some older compilers don't support SFINAE. If your compiler meets
|
|
that criterion, then Boost headers will <tt class="docutils literal"><span class="pre">#define</span></tt> the preprocessor
|
|
symbol <tt class="docutils literal"><span class="pre">BOOST_NO_SFINAE</span></tt>, and uses of <tt class="docutils literal"><span class="pre">parameters<…>::match</span></tt> and
|
|
<tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH</span></tt> will be harmless, but will have no effect.</p>
|
|
</div>
|
|
<div class="section" id="no-support-for-result-of">
|
|
<h2><a name="no-support-for-result-of">3.2 No Support for <a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a></a></h2>
|
|
<p><a class="reference" href="#lazy-default-computation">Lazy default computation</a> relies on the <tt class="docutils literal"><span class="pre">result_of</span></tt> class
|
|
template to compute the types of default arguments given the type
|
|
of the function object that constructs them. On compilers that
|
|
don't support <tt class="docutils literal"><span class="pre">result_of</span></tt>, <tt class="docutils literal"><span class="pre">BOOST_NO_RESULT_OF</span></tt> will be
|
|
<tt class="docutils literal"><span class="pre">#define</span></tt>d, and the compiler will expect the function object to
|
|
contain a nested type name, <tt class="docutils literal"><span class="pre">result_type</span></tt>, that indicates its
|
|
return type when invoked without arguments. To use an ordinary
|
|
function as a default generator on those compilers, you'll need to
|
|
wrap it in a class that provides <tt class="docutils literal"><span class="pre">result_type</span></tt> as a <tt class="docutils literal"><span class="pre">typedef</span></tt>
|
|
and invokes the function via its <tt class="docutils literal"><span class="pre">operator()</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="can-t-declare-parameterspec-via-typedef">
|
|
<h2><a class="toc-backref" href="#id48" name="can-t-declare-parameterspec-via-typedef">3.3 Can't Declare <span class="concept">ParameterSpec</span> via <tt class="docutils literal"><span class="pre">typedef</span></tt></a></h2>
|
|
<p>In principle you can declare a <span class="concept">ParameterSpec</span> as a <tt class="docutils literal"><span class="pre">typedef</span></tt>
|
|
for a specialization of <tt class="docutils literal"><span class="pre">parameters<…></span></tt>, but Microsoft Visual C++
|
|
6.x has been seen to choke on that usage. The workaround is to use
|
|
inheritance and declare your <span class="concept">ParameterSpec</span> as a class:</p>
|
|
<pre class="literal-block">
|
|
<strong>struct dfs_parameters
|
|
:</strong> parameter::parameters<
|
|
tag::graph, tag::visitor, tag::root_vertex
|
|
, tag::index_map, tag::color_map
|
|
> <strong>{};</strong>
|
|
</pre>
|
|
</div>
|
|
<div class="section" id="default-arguments-unsupported-on-nested-templates">
|
|
<h2><a class="toc-backref" href="#id49" name="default-arguments-unsupported-on-nested-templates">3.4 Default Arguments Unsupported on Nested Templates</a></h2>
|
|
<p>As of this writing, Borland compilers don't support the use of
|
|
default template arguments on member class templates. As a result,
|
|
you have to supply <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt> arguments to every
|
|
use of <tt class="docutils literal"><span class="pre">parameters<…>::match</span></tt>. Since the actual defaults used
|
|
are unspecified, the workaround is to use
|
|
<a class="reference" href="#default-arguments-unsupported-on-nested-templates"><tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH</span></tt></a> to declare default arguments for SFINAE.</p>
|
|
</div>
|
|
<div class="section" id="compiler-can-t-see-references-in-unnamed-namespace">
|
|
<h2><a class="toc-backref" href="#id50" name="compiler-can-t-see-references-in-unnamed-namespace">3.5 Compiler Can't See References In Unnamed Namespace</a></h2>
|
|
<p>If you use Microsoft Visual C++ 6.x, you may find that the compiler
|
|
has trouble finding your keyword objects. This problem has been
|
|
observed, but only on this one compiler, and it disappeared as the
|
|
test code evolved, so we suggest you use it only as a last resort
|
|
rather than as a preventative measure. The solution is to add
|
|
<em>using-declarations</em> to force the names to be available in the
|
|
enclosing namespace without qualification:</p>
|
|
<pre class="literal-block">
|
|
namespace graphs
|
|
{
|
|
using graphs::graph;
|
|
using graphs::visitor;
|
|
using graphs::root_vertex;
|
|
using graphs::index_map;
|
|
using graphs::color_map;
|
|
}
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="reference">
|
|
<h1><a class="toc-backref" href="#id51" name="reference">4 Reference</a></h1>
|
|
<p>Follow <a class="reference" href="reference.html">this link</a> to the Boost.Parameter reference
|
|
documentation.</p>
|
|
</div>
|
|
<div class="section" id="acknowledgements">
|
|
<h1><a class="toc-backref" href="#id52" name="acknowledgements">5 Acknowledgements</a></h1>
|
|
<p>The authors would like to thank all the Boosters who participated
|
|
in the review of this library and its documentation, most
|
|
especially our review manager, Doug Gregor.</p>
|
|
<hr class="docutils" />
|
|
<table class="docutils footnote" frame="void" id="old-interface" rules="none">
|
|
<colgroup><col class="label" /><col /></colgroup>
|
|
<tbody valign="top">
|
|
<tr><td class="label"><a class="fn-backref" href="#id2" name="old-interface">[1]</a></td><td>As of Boost 1.33.0 the Graph library was still
|
|
using an <a class="reference" href="../../../graph/doc/bgl_named_params.html">older named parameter mechanism</a>, but there are
|
|
plans to change it to use Boost.Parameter (this library) in an
|
|
upcoming release, while keeping the old interface available for
|
|
backward-compatibility.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<table class="docutils footnote" frame="void" id="odr" rules="none">
|
|
<colgroup><col class="label" /><col /></colgroup>
|
|
<tbody valign="top">
|
|
<tr><td class="label"><a class="fn-backref" href="#id5" name="odr">[2]</a></td><td>The <strong>One Definition Rule</strong> says that any given entity in
|
|
a C++ program must have the same definition in all translation
|
|
units (object files) that make up a program.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<table class="docutils footnote" frame="void" id="vertex-descriptor" rules="none">
|
|
<colgroup><col class="label" /><col /></colgroup>
|
|
<tbody valign="top">
|
|
<tr><td class="label"><a class="fn-backref" href="#id6" name="vertex-descriptor">[3]</a></td><td>If you're not familiar with the Boost Graph
|
|
Library, don't worry about the meaning of any
|
|
Graph-library-specific details you encounter. In this case you
|
|
could replace all mentions of vertex descriptor types with
|
|
<tt class="docutils literal"><span class="pre">int</span></tt> in the text, and your understanding of the Parameter
|
|
library wouldn't suffer.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<table class="docutils footnote" frame="void" id="bind" rules="none">
|
|
<colgroup><col class="label" /><col /></colgroup>
|
|
<tbody valign="top">
|
|
<tr><td class="label"><a class="fn-backref" href="#id15" name="bind">[4]</a></td><td><p class="first">The Lambda library is known not to work on <a class="reference" href="http://www.boost.org/regression/release/user/lambda.html">some
|
|
less-conformant compilers</a>. When using one of those you could
|
|
define</p>
|
|
<pre class="last literal-block">
|
|
template <class T>
|
|
struct construct2
|
|
{
|
|
typedef T result_type;
|
|
|
|
template <class A1, class A2>
|
|
T operator() { return T(a1,a2); }
|
|
};
|
|
|
|
and use Boost.Bind_ to generate the function object::
|
|
|
|
boost::bind(construct2<default_color_map>,num_vertices(g),i)
|
|
</pre>
|
|
</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<table class="docutils footnote" frame="void" id="using" rules="none">
|
|
<colgroup><col class="label" /><col /></colgroup>
|
|
<tbody valign="top">
|
|
<tr><td class="label"><a class="fn-backref" href="#id9" name="using">[5]</a></td><td><p class="first">You can always give the illusion that the function
|
|
lives in an outer namespace by applying a <em>using-declaration</em>:</p>
|
|
<pre class="last literal-block">
|
|
namespace foo_overloads
|
|
{
|
|
// foo declarations here
|
|
void foo() { ... }
|
|
...
|
|
}
|
|
using foo_overloads::foo;
|
|
</pre>
|
|
</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<table class="docutils footnote" frame="void" id="sfinae" rules="none">
|
|
<colgroup><col class="label" /><col /></colgroup>
|
|
<tbody valign="top">
|
|
<tr><td class="label"><a class="fn-backref" href="#id11" name="sfinae">[6]</a></td><td>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 <a class="reference" href="../../../utility/enable_if.html"><tt class="docutils literal"><span class="pre">enable_if</span></tt></a>
|
|
utility. See
|
|
<a class="reference" href="http://www.semantics.org/once_weakly/w02_SFINAE.pdf">http://www.semantics.org/once_weakly/w02_SFINAE.pdf</a> for more
|
|
information on SFINAE.</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<hr class="docutils footer" />
|
|
<div class="footer">
|
|
Generated on: 2005-07-28 16:32 UTC.
|
|
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
|
|
</div>
|
|
</body>
|
|
</html>
|