<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
    <title>Changes between C++14 and C++17</title>
    <style type="text/css">
      html { margin: 0; padding: 0; color: black; background-color: white; }
      body { padding: 2em; font-size: medium; font-family: "DejaVu Serif", serif; line-height: 150%; }
      code { font-family: "DejaVu Sans Mono", monospace; color: #006; }

      h1, h2, h3 { margin: 1.5em 0 .75em 0; line-height: 125%; }

      sup, sub { line-height: 0; }

      div.code { white-space: pre-line; font-family: "DejaVu Sans Mono", monospace;
                 border: thin solid #E0E0E0; background-color: #F8F8F8; padding: 1em;
                 border-radius: 4px; }

      div.strictpre { white-space: pre; }

      div.code em { font-family: "DejaVu Serif", serif; }

      table { border-top: 2px solid black; border-bottom: 2px solid black; border-collapse: collapse; margin: 0 auto 3em auto; }
      thead th { border-bottom: 2px solid black; }
      tr.midsep td { border-top: 2px solid black; }
      th, td { text-align: left; vertical-align: top; padding: 1ex 1ex 1ex 1em; }
      th:first-child, td:first-child { padding-left: 1ex; }

      tr.new td { background-color: #EFE; }
      td.new:after { content: "new!"; font-family: "DejaVu Sans", sans-serif; font-weight: bold; font-size: xx-small;
                     vertical-align: top; top: -1em; right: -1em; position: relative; float: right; color: #090; }

      table.features { width: 100%; }
      .features tr a { font-family: "DejaVu Sans", sans-serif; text-decoration: none; }
      .features tbody tr { border-bottom: thin solid black; }
      .features tr td:first-child { width: 3em; }
      .features tr td:first-child + td { width: 20%; }
      .features tbody tr:hover { background-color: #F9F9FF; }

      .docinfo { float: right }
      .docinfo p { margin: 0; text-align:right; }
      .docinfo address { font-style: normal; }

      .quote { display: inline-block; clear: both; margin-left: 1ex;
               border: thin solid #E0E0E0; background-color: #F8F8F8; padding: 1ex; }

      /*  Use DIV[insert] and DIV[delete] if the entire paragraph is added or removed; otherwise
       *  use DIV[modify] and use INS/DEL elements to mark up individual changes.
       */

      div.insert { border-left: thick solid #0A0; border-right: thick solid #0A0; padding: 0 1em; }
      div.modify { border-left: thick solid #999; border-right: thick solid #999; padding: 0 1em; }
      div.delete { border-left: thick solid #A00; border-right: thick solid #A00; padding: 0 1em; }

      del { color: #A00; text-decoration: line-through; }
      ins { color: #090; }
      ins code, del code { color: inherit; }

      .box { border: thin black solid; padding: 2px; }

      ol { counter-reset: item; }
      ol > li { counter-increment: item; }
      ol ol { list-style: none; padding: 0; }
      ol ol > li:before { content: counters(item, ".") " "; }
    </style>
  </head>
  <body>
    <div class="docinfo">
      <p>ISO/IEC JTC1 SC22 WG21 P0636R0</p>
      <p>Date: 2017-04-02</p>
      <p>To: the public</p>
      <address>
        Thomas K&ouml;ppe &lt;<a href="mailto:tkoeppe@google.com">tkoeppe@google.com</a>&gt;<br>
      </address>
    </div>

    <h1>Changes between C++14 and C++17 DIS</h1>

    <h2>Abstract</h2>

    <p>This document enumerates all the major changes that have been applied to
      the C++ working draft since the publication of C++14, up to the publication
      of the C++17 DIS (N4660). Major changes are those that were added in the form
      of a dedicated paper, excluding those papers that are large issue resolutions.
      No issue resolutions from either CWG or LWG issues lists (&ldquo;defect
      reports&rdquo;) are included.</p>

    <h2>Contents</h2>
    <!-- fgrep -e "<h2 id=" c++17_changes.html | sed -e 's/.*id="\(.*\)">\(.*\)<\/h2>/<li><a href="#\1">\2<\/a><\/li>/g' -->
    <ol>
      <li><a href="#removed">Removed or deprecated features</a></li>
      <li><a href="#new-core-global">New core language features with global applicability</a></li>
      <li><a href="#new-core-local">New core language features with local applicability</a></li>
      <li><a href="#new-lib">New library features</a></li>
      <li><a href="#mods">Modifications to existing features</a></li>
      <li><a href="#misc">Miscellaneous</a></li>
      <li><a href="#unlisted">Unlisted papers</a></li>
      <li><a href="#demo">Assorted snippets demonstrating C++17</a></li>
    </ol>

    <h2 id="removed">Removed or deprecated features</h2>

    <table class="features">
      <thead>
        <tr><th>Document</th><th>Summary</th><th>Examples, notes</th></tr>
      </thead>
      <tbody>
        <tr>
          <td><a href="http://wg21.link/n4086">N4086</a></td>
          <td>Remove trigraphs</td>
          <td>The sequence <code>??!</code> no longer means <code>|</code>. Implementations may offer trigraph-like features as part of their input encoding.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0001r1">P0001R1</a></td>
          <td>Remove <code>register</code></td>
          <td>The <code>register</code> keyword remains reserved, but it no longer has any semantics.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0002r1">P0002R1</a></td>
          <td>Remove <code>++</code> for <code>bool</code></td>
          <td>Increment (<code>++</code>) prefix and postfix expressions are no longer valid for operands of type <code>bool</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0003r5">P0003R5</a></td>
          <td>Remove <code>throw(A, B, C)</code></td>
          <td>Dynamic exception specifications of the form <code>throw(A, B, C)</code>
            are no longer valid. Only <code>throw()</code> remains as a synonym for
            <code>noexcept(true)</code>. Note the change in termination semantics.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0386r2">P0386R2</a></td>
          <td>Deprecate redeclaration of static constexpr class members</td>
          <td>Given <code>struct X { static constexpr int n = 10; };</code>,
            <code>int X::n;</code> is no longer a definition, but instead a
            redundant redeclaration, which is deprecated. The member <code>X::n</code>
            is implicitly inline (see below).</td>
        </tr>

        <tr class="midsep">
          <td><a href="http://wg21.link/n4190">N4190</a></td>
          <td>Remove <code>auto_ptr</code>, <code>random_shuffle</code>,
            old parts of <code>&lt;functional&gt;</code></td>
          <td>Features that have been deprecated since C++11 and replaced with
            superior components are no longer included. Their names remain reserved,
            and implementations may choose to continue to ship the features.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0004r1">P0004R1</a></td>
          <td>Remove deprecated iostream aliases</td>
          <td>Same as above</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0302r1">P0302R1</a></td>
          <td>Remove allocator support from <code>function</code></td>
          <td>The polymorphic function wrapper <code>function</code> no longer has constructors that
            accept an allocator. Allocator support for type-erasing, copyable types is difficult, and
            possibly not implementable efficiently.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0063r3">P0063R3</a> (see below)</td>
          <td>Deprecate C library headers</td>
          <td>The following headers of the &ldquo;C library&rdquo; (this is the term
            for a part of the C++ standard library, <em>not</em> a part of the C
            standard!) are now deprecated: <code>&lt;ccomplex&gt;</code>,
            <code>&lt;cstdalign&gt;</code>, <code>&lt;cstdbool&gt;</code>,
            <code>&lt;ctgmath&gt;</code>. Note that the header
            <code>&lt;ciso646&gt;</code> is not deprecated.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0174r2">P0174R2</a></td>
          <td>Deprecate old library parts</td>
          <td>These library components are now deprecated:
            <code>allocator&lt;void&gt;</code>, <code>raw_storage_iterator</code>,
            <code>get_temporary_buffer</code>, <code>is_literal_type</code>,
            <code>std::iterator</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0618r0">P0618R0</a></td>
          <td>Deprecate <code>&lt;codecvt&gt;</code></td>
          <td>The entire header <code>&lt;codecvt&gt;</code> (which does <em>not</em>
            contain the class <code>codecvt</code>!) is deprecated, as are the
            utilities <code>wstring_convert</code> and <code>wbuffer_convert</code>.
            These features are hard to use correctly, and there are doubts whether they
            are even specified correctly. Users should use dedicated text-processing
            libraries instead.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0371r1">P0371R1</a></td>
          <td>Deprecate <code>memory_order_consume</code> temporarily</td>
          <td>The current semantics of &ldquo;consume&rdquo; ordering have been
            found inadequate, and the ordering needs to be redefined. While this work is
            in progress, hopefully ready for the next revision of C++, users are
            encouraged to not use this ordering and instead use &ldquo;acquire&rdquo;
            ordering, so as to not be exposed to a breaking change in the future.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0521r0">P0521R0</a></td>
          <td>Deprecate <code>shared_ptr::unique</code></td>
          <td>This member function suggests behaviour that is not actually provided.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0604r0">P0604R0</a></td>
          <td>Deprecate <code>result_of</code></td>
          <td>Use the new trait <code>invoke_result</code> instead.</td>
        </tr>
      </tbody>
    </table>

    <h2 id="new-core-global">New core language features with global applicability</h2>

    <p>These are features that may happen to you without your knowledge or consent.</p>

    <table class="features">
      <thead>
        <tr><th>Document</th><th>Summary</th><th>Examples, notes</th></tr>
      </thead>
      <tbody>
        <tr>
          <td><a href="http://wg21.link/p0012r1">P0012R1</a></td>
          <td>Exception specification as part of the type system</td>
          <td>The exception specification of a function is now part of the
            function&rsquo;s type: <code>void f() noexcept(true);</code> and
            <code>void f() noexcept(false);</code> are functions of two distinct
            types. Function pointers are convertible in the sensible direction. (But
            the two functions <code>f</code> may not form an overload set.) This
            change strengthens the type system, e.g. by allowing APIs to require
            non-throwing callbacks.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0135r1">P0135R1</a></td>
          <td>Guaranteed copy elision</td>
          <td>The meaning of <em>prvalue</em> and <em>glvalue</em> has been revised,
            prvalues are no longer objects, but merely &ldquo;initialization&rdquo;.
            Functions returning prvalues no longer copy objects (&ldquo;mandatory copy
            elision&rdquo;), and there is a new prvalue-to-glvalue conversion called
            <em>temporary materialization conversion</em>. This change means that copy
            elision is now guaranteed, and even applies to types that are not copyable
            or movable. This allows you to define functions that return such types.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0035r4">P0035R4</a></td>
          <td>Dynamic allocation of over-aligned types</td>
          <td>Dynamic allocation (<code>operator new</code>) may now support over-aligned
            types, and a new overload of the operator takes an alignment parameter.
            It is still up to the implementation to choose which alignments to support.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0145r3">P0145R3</a></td>
          <td>Stricter order of expression evaluation</td>
          <td>The order of evaluation of certain subexpressions has been specified
            more than it used to be. An important particular aspect of this change is that
            function arguments are now evaluated in an indeterminate order (i.e. no
            interleaving), which was previously merely unspecified. Note that the evaluation
            order for overloaded operators depends on how they are invoked: when invoked using
            operator syntax, the order is the same as for the built-in operator, but when invoked
            using function call syntax, the order is the same as for ordinary
            function calls (i.e. indeterminate).</td>
        </tr>
      </tbody>
    </table>

    <h2 id="new-core-local">New core language features with local applicability</h2>

    <p>These are features where you would know if you were using them.</p>

    <table class="features">
      <thead>
        <tr><th>Document</th><th>Summary</th><th>Examples, notes</th></tr>
      </thead>
      <tbody>
        <tr>
          <td><a href="http://wg21.link/n4267">N4267</a></td>
          <td>A <code>u8</code> character literal</td>
          <td>A character literal prefix <code>u8</code> creates a character that
            is a valid Unicode code point that takes one code unit of UTF-8, i.e.
            an ASCII value: <code>u8'x'</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0245r1">P0245R1</a></td>
          <td>Hexadecimal floating point literals</td>
          <td>Floating point literals with hexadecimal base and decimal exponent:
            <code>0xC.68p+2</code>, <code>0x1.P-126</code>. C has supported this
            syntax since C99, and <code>printf</code> supports it via
            <code>%a</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4295">N4295</a>,
              <a href="http://wg21.link/p0036r0">P0036R0</a></td>
          <td>Fold expressions</td>
          <td>A convenient syntax for applying a binary operator iteratively to the
              elements of a parameter pack: <code>template &lt;typename ...Args&gt;
              auto f(Args ...args) { return <strong>(0 + ... + args)</strong>; }</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0127r2">P0127R2</a></td>
          <td><code>template &lt;auto&gt;</code></td>
          <td>A non-type template parameter may now be declared with placeholder
            type <code>auto</code>.
            Examples:<br>&nbsp;&bull;<code>&nbsp; template &lt;<strong>auto</strong>
            X&gt; struct constant { static constexpr auto value = X; };</code><br>&nbsp;&bull;<code>&nbsp; Delegate&lt;&amp;MyClass::some_function&gt;</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0091r3">P0091R3</a>,
              <a href="http://wg21.link/p0433r2">P0433R2</a>,
              <a href="http://wg21.link/p0512r0">P0512R0</a>,
              <a href="http://wg21.link/p0620r0">P0620R0</a></td>
          <td>Class template argument deduction</td>
          <td>The template arguments of a class template may now be deduced
            from a constructor. For example, <code>pair p(1, 'x');</code>
            defines <code>p</code> as <code>pair&lt;int, char&gt;</code> (this is not
            an HTML error, the template arguments were omitted deliberately). The implicit
            deduction is complemented by a system of explicit deduction guides which
            allow authors to customise how the deduction happens, or forbid it.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0292r2">P0292R2</a></td>
          <td>Constexpr <code>if</code></td>
          <td>In a template specialization, the arms of the new <code>if
            <strong>constexpr</strong> (<em>condition</em>)</code> statement
            are only instantiated if the condition (which must be a constant
            expression) has the appropriate value.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0305r1">P0305R1</a></td>
          <td>Selection statements with initializer</td>
          <td>The selection statements <code>if</code> and <code>switch</code> gain
            a new, optional initializer part: <code>if (auto it = m.find(key);
            it != m.end()) return it-&gt;second; </code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0170r1">P0170R1</a></td>
          <td>Constexpr lambdas</td>
          <td>Lambda expressions may now be constant expressions: <code>auto add =
            [](int a, int b) <strong>constexpr</strong> { return a + b; };
            int arr[add(1, 2)];</code></td>

        <tr>
          <td><a href="http://wg21.link/p0018r3">P0018R3</a></td>
          <td>Lambda capture of <code>*this</code></td>
          <td>Before: <code>[self = *this]{ self.f(); }</code>
            Now: <code>[<strong>*this</strong>]{ f(); }</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0386r2">P0386R2</a></td>
          <td>Inline variables</td>
          <td>In a header file: <code><strong>inline</strong> int n = 10;</code>
            All definitions refer to the same entity. Implied for static constexpr
            class data members.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0217r3">P0217R3</a>,
              <a href="http://wg21.link/p0615r0">P0615R0</a></td>
          <td>Structured bindings</td>
          <td><code><strong>auto [it, ins]</strong> = m.try_emplace(key, a1, a2, a3);</code><br>
            Decomposes arrays, all-members-public classes, and user-defined types that
            follow a <code>get&lt;N&gt;</code> protocol like <code>pair</code>
            and <code>tuple</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0061r1">P0061R1</a></td>
          <td><code>__has_include</code></td>
          <td>A preprocessor operator to check whether an inclusion is possible.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0188r1">P0188R1</a><br>
              <a href="http://wg21.link/p0189r1">P0189R1</a><br>
              <a href="http://wg21.link/p0212r1">P0212R1</a></td>
          <td>Attribute <code>[[fallthrough]]</code><br>
              Attribute <code>[[nodiscard]]</code><br>
              Attribute <code>[[maybe_unused]]</code></td>
          <td>A new set of standardised attributes. The attributes formally have
            no required semantics, but implementations are encouraged to emit or
            suppress the appropriate diagnostics (warnings).</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0137r1">P0137R1</a></td>
          <td><code>launder</code></td>
          <td>A language support tool (an &ldquo;optimisation barrier&rdquo;) to allow
            libraries to reuse storage and access
            that storage through an old pointer, which was previously not allowed.
            (This is an expert tool for implementers and not expected to show up in
            &ldquo;normal&rdquo; code.)</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0298r3">P0298R3</a></td>
          <td>A byte type</td>
          <td>A new type <code>byte</code> is defined in <code>&lt;cstddef&gt;</code>
            (not in <code>&lt;stddef.h&gt;</code>, and only in namespace <code>std</code>!)
            which has the layout of <code>unsigned char</code>, shares the aliasing
            allowances of the existing char types, and has bitwise operations defined.</td>
        </tr>
      </tbody>
    </table>

    <h2 id="new-lib">New library features</h2>

    <table class="features">
      <thead>
        <tr><th>Document</th><th>Summary</th><th>Examples, notes</th></tr>
      </thead>
      <tbody>
        <tr>
          <td><a href="http://wg21.link/p0226r1">P0226R1</a></td>
          <td>Mathematical special functions</td>
          <td>The contents of the former international standard
            ISO/IEC 29124:2010 (mathematical special functions)
            are now part of C++. The functions were added only to
            <code>&lt;cmath&gt;</code>, not to <code>&lt;math.h&gt;</code>,
            and are only available in namespace <code>std</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0218r0">P0218R0</a>,
              <a href="http://wg21.link/p0219r1">P0219R1</a>,
              <a href="http://wg21.link/p0317r1">P0317R1</a>,
              <a href="http://wg21.link/p0392r0">P0392R0</a>,
              <a href="http://wg21.link/p0430r2">P0430R2</a>,
              <a href="http://wg21.link/p0492r2">P0492R2</a></td>
          <td>Filesystem</td>
          <td>The contents of the Filesystems Technical Specification are
            now part of C++. The filesystems library allows portable interaction
            with directories and directory-like structures (listing directory contents,
            moving files, etc.). It is largely modelled on POSIX, but flexible enough
            to be implementable for a wide variety of systems.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0024r2">P0024R2</a>,
              <a href="http://wg21.link/p0336r1">P0336R1</a>,
              <a href="http://wg21.link/p0394r4">P0394R4</a>,
              <a href="http://wg21.link/p0452r1">P0452R1</a>,
              <a href="http://wg21.link/p0467r2">P0467R2</a>,
              <a href="http://wg21.link/p0502r0">P0502R0</a>,
              <a href="http://wg21.link/p0518r1">P0518R1</a>,
              <a href="http://wg21.link/p0523r1">P0523R1</a>,
              <a href="http://wg21.link/p0574r1">P0574R1</a>,
              <a href="http://wg21.link/p0623r0">P0623R0</a></td>
          <td>Parallelism</td>
          <td>The contents of the Parallelism Technical Specification are now part of C++.
            This adds new overloads, taking an additional <em>execution policy</em>
            argument, to many algorithms, as well as entirely new algorithms (see below).
            Three execution policies are supported, which respectively provide sequential,
            parallel, and vectorized execution.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0024r2">P0024R2</a></td>
          <td>New algorithms</td>
          <td>The Parallelism Technical Specification adds several new algorithms
            to the standard library. They are motivated by their potential for
            efficient parallel execution, but are available in the usual simple
            form as well: <code>for_each_n</code>, <code>reduce</code>, <code>transform_reduce</code>,
            <code>exclusive_scan</code>, <code>inclusive_scan</code>, <code>transform_exclusive_scan</code>,
            <code>transform_inclusive_scan</code>. Note that <code>reduce</code>
            looks similar to the existing <code>accumulate</code>, but does not
            guarantee any particular order of operations.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P02202</a>,
              <a href="http://wg21.link/p0254r2">P0254R2</a>,
              <a href="http://wg21.link/p0403r1">P0403R1</a></td>
          <td>New type: <code>string_view</code> (and <code>basic_string_view</code>)</td>
          <td>The new <code>string_view</code> class is the preferred interface vocabulary
            type for APIs that need to view a string without wanting to take ownership or to
            modify it. It is constructible from char pointers, but all other classes that
            are string-like should offer conversions <em>to</em> <code>string_view</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P02202</a>,
              <a href="http://wg21.link/p0032r3">P0032R3</a>,
              <a href="http://wg21.link/p0504r0">P0504R0</a></td>
          <td>New type: <code>any</code></td>
          <td>The type <code>any</code> type-erases copyable objects. There are essentially
            three things you can do with an <code>any</code>: 1. put a value of type <code>T</code>
            into it. 2. Make a copy of it. 3. Ask it whether it contains a value of type <code>U</code>
            and get that value out, which succeeds if and only if <code>U</code> is <code>T</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0088r3">P0088R3</a>,
              <a href="http://wg21.link/p0393r3">P0393R3</a>,
              <a href="http://wg21.link/p0032r3">P0032R3</a>,
              <a href="http://wg21.link/p0504r0">P0504R0</a>,
              <a href="http://wg21.link/p0510r0">P0510R0</a></td>
          <td>New class template: <code>variant</code></td>
          <td>A variant models a disjoint union (or discriminated union). A value of
            <code>variant&lt;A, B, C&gt;</code> contains <em>one of</em> an <code>A</code>,
            a <code>B</code>, or a <code>C</code> at any one time.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P02202</a>,
              <a href="http://wg21.link/p0307r2">P0307R2</a>,
              <a href="http://wg21.link/p0032r3">P0032R3</a>,
              <a href="http://wg21.link/p0504r0">P0504R0</a></td>
          <td>New class template: <code>optional</code></td>
          <td>An optional value. A <code>optional&lt;T&gt;</code> represents either a
          <code>T</code> value, or no value (which is signified by the tag type
          <code>nullopt_t</code>). In some respects this can be thought of as
          equivalent to <code>variant&lt;nullopt_t, T&gt;</code>, but with a purpose-built
          interface.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4169">N4169</a></td>
          <td><code>invoke</code></td>
          <td>A facility to uniformly invoke callable entities. This allows users
            to write libraries with the same behaviour as the standard&rsquo;s
            magic <code><em>INVOKE</em></code> rule.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0077r2">P0077R2</a>,
              <a href="http://wg21.link/p0604r0">P0604R0</a></td>
          <td><code>is_invocable</code>, <code>is_invocable_r</code>,
            <code>invoke_result</code></td>
          <td>Traits to reason about invocability and invocation results.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0067r5">P0067R5</a></td>
          <td>Elementary string conversions</td>
          <td>Functions <code>to_chars</code>, <code>from_chars</code> that produce
            or parse string representations of numbers. These are intended to form
            an efficient, low-level basis for a replacement for <code>printf</code>
            and iostream formatted operations. They follow idiomatic C++ algorithm
            style.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n3911">N3911</a></td>
          <td>Alias template <code>void_t</code></td>
          <td><code>template &lt;class...&gt; using void_t = void;</code> Surprisingly
            useful for metaprogramming, to simplify use of SFINAE.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4389">N4389</a></td>
          <td>Alias template <code>bool_constant</code></td>
          <td><code>template &lt;bool B&gt; using bool_constant =
            integral_constant&lt;bool, B&gt;</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0013r1">P0013R1</a></td>
          <td>Logical operation metafunctions</td>
          <td>Variadic metafunctions <code>conjunction</code>, <code>disjunction</code>, and
            <code>negation</code> for metaprogramming. These traits short-circuit in the
            metaprogramming sense: template specializations that are not required to
            determine the result are not instantiated.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0185r1">P0185R1</a></td>
          <td>Traits for SFINAE-friendly <code>swap</code></td>
          <td>New traits <code>is_{,nothrow_}swappable</code>,
            <code>is_{,nothrow_}swappable_with</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/lwg2911">LWG 2911</a></td>
          <td>Trait <code>is_aggregate</code></td>
          <td>Whether a type is an aggregate. Useful for example
            to tell whether a generic type should be list- or
            non-list-initialized.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0258r2">P0258R2</a></td>
          <td>Trait <code>has_unique_object_representations</code></td>
          <td>This trait may be used to reason about whether certain value-based
            operations like comparison and hashing can be replaced with
            representation-based operations (e.g. <code>memcmp</code>).</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0007r1">P0007R1</a></td>
          <td><code>as_const</code></td>
          <td>Given an lvalue <code>x</code>, <code>as_const(x)</code> returns
            the const-qualified version. Does not bind to rvalues.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4280">N4280</a></td>
          <td>Non-member <code>size</code>, <code>data</code>, <code>empty</code></td>
          <td>The additional functions complement the existing free functions
            <code>begin</code>, <code>end</code> etc. to access containers and
            arrays in a uniform fashion. Note that unlike
            <code>begin</code>/<code>end</code>, the new functions are <em>not</em>
            customisation points for anything and are only provided for convenience.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0025r0">P0025R0</a></td>
          <td><code>clamp</code></td>
          <td><code>clamp(x, low, high)</code> returns either <code>x</code> if
            <code>x</code> is within the interval <code>[low, high]</code>,
            or the nearest bound otherwise.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0295r0">P0295R0</a></td>
          <td><code>gcd</code> and <code>lcm</code></td>
          <td>Number-theoretic functions to compute the greatest common divisor
            and least common multiple of two integers.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4508">N4508</a></td>
          <td>Class <code>shared_mutex</code></td>
          <td>A reader-writer mutex, which can be locked in either shared or
            exclusive mode.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0154r1">P0154R1</a></td>
          <td>Interference sizes</td>
          <td>Two new implementation-defined constants
            <code>hardware_{con,de}structive_interference_size</code>
            that effectively allow the platform to document its cache line sizes
            so that users can avoid false sharing (destructive interference) and
            improve locality (constructive interference). Two separate constants
            are defined to support heterogeneous architectures.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P0220R1</a></td>
          <td>Tuple <code>apply</code></td>
          <td>Invokes a callable with arguments extracted from a given tuple.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0209r2">P0209R2</a></td>
          <td>Construction from tuples</td>
          <td>A new function template <code>make_from_tuple</code> that initializes
            a value of type <code>T</code> from the elements of a given tuple. It
            is like <code>apply</code> applied to a constructor.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0005r4">P0005R4</a>,
              <a href="http://wg21.link/p0358r1">P0358R1</a></td>
          <td>Universal negator <code>not_fn</code></td>
          <td>A call wrapper that negates its wrapped callable. This works with callables
            of any arity and replaces the old <code>not1</code> and <code>not2</code>
            wrappers.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P0220R1</a></td>
          <td>Memory resources</td>
          <td>A new set of components comprised of a <em>memory resource</em> base class
            for dynamically selectable memory providers, as well as three concrete
            implementations (<code>synchronized_pool_resource</code>,
            <code>unsynchronized_pool_resource</code>, <code>monotonic_buffer_resource</code>).
            See next item for use cases.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P0220R1</a>,
              <a href="http://wg21.link/p0337r0">P0337R0</a></td>
          <td>A polymorphic allocator</td>
          <td>An allocator that uses a memory resource, which can be changed
            at runtime and is not part of the allocator type. Also contains
            convenience type aliases like <code>std::pmr::vector&lt;T&gt; =
            std::vector&lt;T, polymorphic_allocator&lt;T&gt;&gt;</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P0220R1</a>,
              <a href="http://wg21.link/p0253r1">P0253R1</a></td>
          <td>Searcher functors</td>
          <td>Substring searcher functors implementing the Boyer-Moore and
            Boyer-Moore-Horspool algorithms, and a <code>search</code> algorithm
            using those functors.</td>
        </tr>

        <!-- tr>
          <td><a href="http://wg21.link/p0220r1">P0220R1</a></td>
          <td>Library Fundamentals TS (v1)</td>
          <td>Some of the contents of the Library Fundamentals Technical
            Specification (v1) were added to C++. Some of those parts are
            mentioned in separate entries.</td>
        </tr -->
      </tbody>
    </table>

    <h2 id="mods">Modifications to existing features</h2>

    <table class="features">
      <thead>
        <tr><th>Document</th><th>Summary</th><th>Examples, notes</th></tr>
      </thead>
      <tbody>
        <tr>
          <td><a href="http://wg21.link/n3928">N3928</a></td>
          <td>Single-argument <code>static_assert</code></td>
          <td>The <code>static_assert</code> declaration no longer requires
            a second argument: <code>static_assert(N &gt; 0);</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4230">N4230</a></td>
          <td>Nested namespace declarations</td>
          <td><code>namespace <strong>foo::bar</strong> { /* ... */ }</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4051">N4051</a></td>
          <td>Allow <code>typename</code> in template template parameters</td>
          <td><code>template &lt;template &lt;typename&gt; <strong>typename</strong>
            Tmpl&gt; struct X;</code> Previously, template template parameters
            were required to use the keyword <code>class</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0184r0">P0184R0</a></td>
          <td>Range-based <code>for</code> takes separate begin/end types</td>
          <td>The rewrite rule for <code>for (<em>decl</em> : <em>expr</em>)</code> now
            says <code>auto __begin = <em>begin-expr</em>; auto __end =
            <em>end-expr</em>;</code>, as opposed to <code>auto __begin =
            <em>begin-expr</em>, __end = <em>end-expr</em>;</code> before.
            This prepares the range-based <code>for</code> statement for the new
            Ranges (work in progress).</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0195r2">P0195R2</a></td>
          <td>Pack expansion in <em>using-declaration</em>s</td>
          <td><code>template &lt;typename ...Args&gt; struct X : Args... {
            <strong>using Args::f...;</strong> };</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0138r2">P0138R2</a></td>
          <td>Construction for values of fixed enums</td>
          <td>A variable of a fixed enumeration <code>E</code> can now be defined
            with <code>E e { 5 };</code> and no longer requires the the more cumbersome
            <code>E e { E(5) };</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4259">N4259</a></td>
          <td><code>uncaught_exceptions()</code></td>
          <td>The function <code>uncaught_exception</code> is deprecated, the
            new function <code>uncaught_exceptions</code> returns a count rather
            than a boolean. The previous feature was effectively unusable;
            <a href="http://wg21.link/n4152">N4152</a> explains the details.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4266">N4266</a></td>
          <td>Attributes in namespaces and enumerators</td>
          <td>Namespaces and enumerators can now be annotated with attributes. This
            allows, for example, to deprecate namespaces or enumerators.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0028r4">P0028R4</a></td>
          <td>Attribute namespaces without repetition</td>
          <td>This simplifies the use of attribute namespace qualifications when
            a namespace is used repeatedly.</td>
        </tr>

        <tr class="midsep">
          <td><a href="http://wg21.link/n4279">N4279</a></td>
          <td>Improved insertion for unique-key maps</td>
          <td><code>m.try_emplace(key, arg1, arg2, arg3)</code> does nothing if <code>key</code>
            already exists in the map, and otherwise inserts a new element constructed from the
            arguments. This interface guarantees that even if the arguments are bound to rvalue
            references, they are not moved from if the insertion does not take place.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0084r2">P0084R2</a></td>
          <td>Return type of <code>emplace</code></td>
          <td>Sequence containers whose <code>emplace{,_front,_back}</code>
            member function templates used to return <code>void</code> now
            return a reference to the newly inserted element. (Associative
            containers are not affected, since their insertion functions have
            always returned iterators to the relevant element.)</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0083r3">P0083R3</a>,
              <a href="http://wg21.link/p0508r0">P0508R0</a></td>
          <td>Splicing maps and sets</td>
          <td>A new mechanism, <em>node handles</em>, has been added to the
            container library that allows transplanting elements between different
            map/set objects without touching the contained object. Moreover, this
            technique enables mutable access to key values of extracted nodes.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0272r1">P0272R1</a></td>
          <td>Non-const <code>string::data</code></td>
          <td>There is now a non-const overload of <code>basic_string::data</code>
            that returns a mutable pointer. Moreover, C++17 allows writing to the
            null terminator, provided that the value zero is written. This makes
            the string classes a bit more convenient to use with C-style interfaces.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0156r0">P0156R0</a>,
              <a href="http://wg21.link/p0156r2">P0156R2</a></td>
          <td>A variadic version of <code>lock_guard</code> called
            <code>scoped_lock</code></td>
          <td>A new, variadic class template <code>scoped_lock&lt;Args...&gt;</code>
            that locks multiple lockable objects at once (using the same algorithm
            as <code>lock</code>) and releases them in the destructor. Initially
            it was suggested to simply change the definition of <code>lock_guard</code>
            to become variadic, but this was discovered to be a breaking change, and
            so instead we now have a new class template <code>scoped_lock</code> that
            is strictly superior to the old <code>lock_guard</code> and should be
            used instead.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0006r0">P0006R0</a></td>
          <td>Variable templates for traits</td>
          <td>For every standard type trait <code>foo</code> with a single, static member
            constant <code>foo&lt;Args...&gt;::value</code>, there is now a
            variable template <code>foo_v&lt;Args...&gt;</code>.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0152r1">P0152R1</a></td>
          <td><code>atomic::is_always_lock_free</code></td>
          <td>A new static member constant <code>is_always_lock_free</code> that
            documents whether the operations of a given atomic type are always lock-free.
            The existing non-static member function <code>is_lock_free</code> may
            give different answers for different values of the atomic type.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0220r1">P0220R1</a>,
              <a href="http://wg21.link/p0414r2">P0414R2</a></td>
          <td><code>shared_ptr</code> for arrays</td>
          <td>The class template <code>shared_ptr</code> now supports C-style arrays
            by passing <code>T[]</code> or <code>T[N]</code> as the template argument,
            and the constructor from a raw pointer will install an appropriate array
            deleter.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0163r0">P0163R0</a></td>
          <td><code>shared_ptr::weak_type</code></td>
          <td>The class <code>shared_ptr&lt;T&gt;</code> now has a member type
            <code>weak_type</code> which is <code>weak_ptr&lt;T&gt;</code>. This
            allows generic code to name the corresponding weak pointer type without
            having to destructure the shared pointer type.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0030r1">P0030R1</a></td>
          <td>Three-dimensional hypotenuse</td>
          <td>The three-dimensional hypotenuse <code>hypot(x, y, z)</code> is
            added as an additional set of overloads to <code>&lt;cmath&gt;</code> (but not
            to <code>&lt;math.h&gt;</code> and only to namespace <code>std</code>).</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0040r3">P0040R3</a></td>
          <td>Further uninitialized algorithms</td>
          <td>Additional algorithms to create objects in uninitialized memory
            and to destroy objects. Separate versions for default- and value-initialization
            are included.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4510">N4510</a></td>
          <td>Incomplete type support for allocators</td>
          <td>This change relaxes the requirements on allocators to have complete
            value types, and allows, for example, recursive structures like:
            <code>struct X { std::vector&lt;X&gt; data; };</code></td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0092r1">P0092R1</a>,
              <a href="http://wg21.link/p0505r0">P0505R0</a></td>
          <td>Changes to <code>&lt;chrono&gt;</code></td>
          <td>Adds floor, ceiling, division and rounding for time points; makes most
            member functions constexpr.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0426r1">P0426R1</a></td>
          <td>Constexpr for <code>char_traits</code></td>
          <td>All specializations required for <code>char_traits</code> now have
            constexpr member functions <code>length</code>, <code>compare</code>,
            <code>find</code> and <code>assign</code>, allowing string views
            to be more widely used in constant expressions.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4387">N4387</a></td>
          <td>Improving <code>pair</code> and <code>tuple</code></td>
          <td>This change makes the constructors of <code>pair</code> and
            <code>tuple</code> as explicit as the corresponding element type
            constructors.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0435r1">P0435R1</a>,
              <a href="http://wg21.link/p0548r1">P0548R1</a></td>
          <td>Changes to <code>common_type</code></td>
          <td>Because it&rsquo;s not a new standard if we didn&rsquo;t make changes
            to <code>common_type</code>&hellip;</td>
        </tr>
      </tbody>
    </table>

    <h2 id="misc">Miscellaneous</h2>

    <table class="features">
      <thead>
        <tr><th>Document</th><th>Summary</th><th>Examples, notes</th></tr>
      </thead>
      <tbody>
        <tr>
          <td><a href="http://wg21.link/p0063r3">P0063R3</a></td>
          <td>C++ refers to C11</td>
          <td>The C++ standard now refers normatively to C11 (ISO/IEC 9899:2011) as
            &ldquo;The C Standard&rdquo;. Not only does ISO require that references to
            other international standards refer to the latest published version, and not
            to a historic version, but this also gives us access to
            <code>aligned_alloc</code>, which is useful for the improvements to our
            dynamic memory management.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0180r2">P0180R2</a></td>
          <td>Reserved namespaces</td>
          <td>All top-level namespaces of the form <code>std<em>X</em></code>,
            where <code><em>X</em></code> is a sequence of digits, are reserved.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0175r1">P0175R1</a></td>
          <td>C library synopses</td>
          <td>A purely editorial change: all headers of the &ldquo;C library&rdquo; part
            of the standard library are now presented as complete synopses in the C++
            standard document, rather than as just lists of names. This makes the changes
            in semantics from C easier to appreciate (e.g. additional overloads, overloads
            on language linkage).</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/n4262">N4262</a><br>
              <a href="http://wg21.link/p0134r0">P0134R0</a><br>
              <a href="http://wg21.link/p0391r0">P0391R0</a><br>
              <a href="http://wg21.link/n4284">N4284</a></td>
          <td>Term &ldquo;forwarding reference&rdquo;<br>
              Term &ldquo;default member initializer&rdquo;<br>
              Term &ldquo;templated entity&rdquo;<br>
              Term &ldquo;contiguous iterator&rdquo;</td>
          <td>These changes have no normative impact, but they establish official
            terminology for concepts that have so far only <em>emerged</em> from the
            language rules. Having precise and well-known terms simplifies talking
            about C++ and simplifies the specification.</td>
        </tr>

        <tr>
          <td><a href="http://wg21.link/p0346r1">P0346R1</a></td>
          <td>Change &ldquo;random number generator&rdquo; to
            &ldquo;random bit generator&rdquo;</td>
          <td>Similarly, this change has no normative impact, but clarifies the
            design and intended use of this aspect of the <code>&lt;random&gt;</code>
            facilities.</td>
        </tr>
      </tbody>
    </table>

    <h2 id="unlisted">Unlisted papers</h2>

    <p>The following papers were moved at committee meetings, but their
      contents are too specific to call out as separate features:
      <a href="http://wg21.link/n3922">N3922</a>,
      <a href="http://wg21.link/n4089">N4089</a>,
      <a href="http://wg21.link/n4258">N4258</a>,
      <a href="http://wg21.link/n4261">N4261</a>,
      <a href="http://wg21.link/n4268">N4268</a>,
      <a href="http://wg21.link/n4277">N4277</a>,
      <a href="http://wg21.link/n4285">N4285</a>,
      <a href="http://wg21.link/p0017r1">P0017R1</a>,
      <a href="http://wg21.link/p0031r0">P0031R0</a>,
      <a href="http://wg21.link/p0033r1">P0033R1</a>,
      <a href="http://wg21.link/p0074r0">P0074R0</a>,
      <a href="http://wg21.link/p0136r1">P0136R1</a>,
      <a href="http://wg21.link/p0250r3">P0250R3</a>,
      <a href="http://wg21.link/p0270r3">P0270R3</a>,
      <a href="http://wg21.link/p0283r2">P0283R2</a>,
      <a href="http://wg21.link/p0296r2">P0296R2</a>,
      <a href="http://wg21.link/p0418r2">P0418R2</a>,
      <a href="http://wg21.link/p0503r0">P0503R0</a>,
      <a href="http://wg21.link/p0509r1">P0509R1</a>,
      <a href="http://wg21.link/p0513r0">P0513R0</a>,
      <a href="http://wg21.link/p0516r0">P0516R0</a>,
      <a href="http://wg21.link/p0517r0">P0517R0</a>,
      <a href="http://wg21.link/p0558r1">P0558R1</a>,
      <a href="http://wg21.link/p0599r1">P0599R1</a>,
      <a href="http://wg21.link/p0607r0">P0607R0</a>,
      <a href="http://wg21.link/p0612r0">P0612R0</a>
    </p>

    <p>The following papers contain issues that have been accepted as defect reports. CWG issues are handled by
      <a href="http://wg21.link/n4192">N4192</a>,
      <a href="http://wg21.link/n4457">N4457</a>,
      <a href="http://wg21.link/p0164r0">P0164R0</a>,
      <a href="http://wg21.link/p0167r2">P0167R2</a>,
      <a href="http://wg21.link/p0263r1">P0263R1</a>,
      <a href="http://wg21.link/p0384r0">P0384R0</a>,
      <a href="http://wg21.link/p0398r0">P0398R0</a>,
      <a href="http://wg21.link/p0490r0">P0490R0</a>,
      <a href="http://wg21.link/p0507r0">P0507R0</a>,
      <a href="http://wg21.link/p0519r0">P0519R0</a>,
      <a href="http://wg21.link/p0520r0">P0520R0</a>,
      <a href="http://wg21.link/p0522r0">P0522R0</a>,
      <a href="http://wg21.link/p0575r1">P0575R1</a>,
      <a href="http://wg21.link/p0576r1">P0576R1</a>,
      <a href="http://wg21.link/p0613r0">P0613R0</a>,
      <a href="http://wg21.link/p0622r0">P0622R0</a>.
      LWG issues are handled by
      <a href="http://wg21.link/n4245">N4245</a>,
      <a href="http://wg21.link/n4366">N4366</a>,
      <a href="http://wg21.link/n4383">N4383</a>,
      <a href="http://wg21.link/n4525">N4525</a>,
      <a href="http://wg21.link/p0165r0">P0165R0</a>,
      <a href="http://wg21.link/p0165r1">P0165R1</a>,
      <a href="http://wg21.link/p0165r2">P0165R2</a>,
      <a href="http://wg21.link/p0165r2">P0165R2</a>,
      <a href="http://wg21.link/p0165r3">P0165R3</a>,
      <a href="http://wg21.link/p0165r4">P0165R4</a>,
      <a href="http://wg21.link/p0304r1">P0304R1</a>,
      <a href="http://wg21.link/p0397r0">P0397R0</a>,
      <a href="http://wg21.link/p0610r0">P0610R0</a>,
      <a href="http://wg21.link/p0625r0">P0625R0</a>.
      Only specific issues may have been selected from each paper; the meeting minutes contain the details.
    </p>

    <h2 id="demo">Assorted snippets demonstrating C++17</h2>

    <div class="code"><!--
    -->std::unordered_map&lt;std::string, std::unique_ptr&lt;Foo&gt;&gt; items;
      std::vector&lt;std::unique_ptr&lt;Foo&gt;&gt; standby;

      // If there is currently no item 'id', installs 'foo' as item 'id'.
      // Otherwise stores 'foo' for later use and puts it on standby.

      <span style="color:#A00;"><strong>// Before C++17</strong>

      void f(std::string id, std::unique_ptr&lt;Foo&gt; foo) {
      &nbsp; auto it = items.find(id);
      &nbsp; if (it == items.end()) {
      &nbsp; &nbsp; auto p = items.emplace(std::move(id), std::move(foo));
      &nbsp; &nbsp; p.first-&gt;second-&gt;launch();
      &nbsp; } else {
      &nbsp; &nbsp; standby.push_back(std::move(foo));
      &nbsp; &nbsp; standby.back()-&gt;wait_for_notification();
      &nbsp; }

      <span style="color: #666;">&nbsp; // Notes:
      &nbsp; // * Variable 'id' can no longer be used (moved-from); or...
      &nbsp; // * ...would need to use parameter 'const string&amp; id' and force copying.
      &nbsp; // * Map lookup performed twice. Ordered map could use lower_bound + hint, but unordered map cannot.
      &nbsp; // * (Cannot emplace unconditionally, because it might destroy *foo.)</span>
      }</span>

      <span style="color:#060;">// <strong style="color: #070;">With C++17</strong>

      void f(std::string_view id, std::unique_ptr&lt;Foo&gt; foo) {
      &nbsp; if (auto [pos, inserted] = items.try_emplace(id, std::move(foo)); inserted) {
      &nbsp; &nbsp; pos-&gt;second-&gt;launch();
      &nbsp; } else {
      &nbsp; &nbsp; standby.emplace_back(std::move(foo))-&gt;wait_for_notification();
      &nbsp; }
      }</span>
    </div>

    <p>The next snippet illustrates the utility of <code>template &lt;auto&gt;</code>
      on the example of a class template which delegates a free function call to a
      member function bound to a class instance, and the member function is part of
      the delegate <em>type</em>.</p>

    <div class="code"><span style="color:#A00;"><strong>// Before C++17</strong>

      template &lt;typename T, int (T::* MF)(int, int)&gt; &nbsp; <span style="color: #666;">// two params: one type, one non-type</span>
      struct Delegate</span> { /* ... */ };

      int n = <span style="color:#A00;">Delegate&lt;MyComplexClass, &amp;MyComplexClass::an_imporant_function&gt;</span>(&amp;obj)(10, 20);

      <span style="color:#060;">// <strong style="color: #070;">With C++17</strong>

      template &lt;auto&gt; struct Delegate; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666;">// one (non-type) param</span>
      template &lt;typename T, int (T::* MF)(int, int)&gt;
      struct Delegate&lt;MF&gt;</span> { /* ... */ }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666;">// implement as before, but as partial specialization</span>

      int n = <span style="color:#060;">Delegate&lt;&amp;MyComplexClass::an_imporant_function&gt;</span>(&amp;obj)(10, 20);
    </div>

    <p>The next snippet shows the utility of fold expressions in generic code.</p>

    <div class="code"><span style="color: #666;">// Call f(n) for all f in the pack.</span>
      template &lt;typename ...F&gt;
      void ApplyAll(int n, const F&amp;... f) {
      &nbsp; <span style="color:#060;">(f(n), ...);</span> <span style="color: #666;">// unary fold (over the comma operator)</span>
      }

      <span style="color: #666;">// Compute f(a, b) for each f in the pack and return the sum.</span>
      template &lt;typename ...F&gt;
      int ApplyAndSum(int a, int b, const F&amp;... f) {
      &nbsp; <span style="color:#060;">return (f(a, b) + ... + 0);</span> <span style="color: #666;">// binary fold</span>
      }
    </div>
    
    <p>The next snippet shows array support for shared pointers.</p>

    <div class="code"><span style="color:#A00;"><strong>// Before C++17</strong>
      std::shared_ptr&lt;char&gt; p(new char[N], std::default_delete&lt;char[]&gt;());</span> <span style="color: #666;">// would be wrong without the deleter</span>

      <span style="color:#060;">// <strong style="color: #070;">With C++17</strong>
      std::shared_ptr&lt;char[]&gt; p(new char[N]);</span> <span style="color: #666;">// deleter uses &ldquo;delete[]&rdquo;</span>
    </div>

  </body>
</html>
