<!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">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title>Suggested Design for Customization Points</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
  </style>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="607">
  <tr>
    <td width="172" align="left" valign="top">Document number:</td>
    <td width="435">
      <span style="background-color: #FFFF00">N4381</span>=yy-nnnn
    </td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Date:</td>
    <td width="435">2015-03-11</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Project:</td>
    <td width="435">Programming Language C++, Library Working Group</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Reply-to:</td>
    <td width="435">
      Eric Niebler &lt;<a href="mailto:eniebler@boost.org">eniebler@boost.org</a>&gt;,<br/>
    </td>
  </tr>
</table>
<div id="header">
<h1 class="title">Suggested Design for Customization Points</h1>
</div>
<div id="TOC">
<ul>
<li><a href="#introduction"><span class="toc-section-number">1</span> Introduction</a></li>
<li><a href="#motivation-and-scope"><span class="toc-section-number">2</span> Motivation and Scope</a><ul>
<li><a href="#impact-on-the-standard"><span class="toc-section-number">2.1</span> Impact on the Standard</a></li>
</ul></li>
<li><a href="#proposed-design"><span class="toc-section-number">3</span> Proposed Design</a><ul>
<li><a href="#design-goals"><span class="toc-section-number">3.1</span> Design Goals</a></li>
<li><a href="#design-details"><span class="toc-section-number">3.2</span> Design Details</a></li>
<li><a href="#analysis"><span class="toc-section-number">3.3</span> Analysis</a><ul>
<li><a href="#qualified-and-unqualified-calls-should-behave-identically"><span class="toc-section-number">3.3.1</span> Qualified and unqualified calls should behave identically</a></li>
<li><a href="#unqualified-calls-should-not-bypass-constraints-checking"><span class="toc-section-number">3.3.2</span> Unqualified calls should not bypass constraints checking</a></li>
<li><a href="#calls-to-the-customization-point-should-be-optimally-efficient"><span class="toc-section-number">3.3.3</span> Calls to the customization point should be optimally efficient</a></li>
<li><a href="#no-violations-of-the-one-definition-rule"><span class="toc-section-number">3.3.4</span> No violations of the one-definition rule</a></li>
<li><a href="#no-executable-bloat"><span class="toc-section-number">3.3.5</span> No executable bloat</a></li>
</ul></li>
<li><a href="#hooking-the-customization-point"><span class="toc-section-number">3.4</span> Hooking the Customization Point</a></li>
</ul></li>
<li><a href="#design-drawbacks"><span class="toc-section-number">4</span> Design Drawbacks</a></li>
<li><a href="#implementation-experience"><span class="toc-section-number">5</span> Implementation Experience</a></li>
<li><a href="#alternative-designs"><span class="toc-section-number">6</span> Alternative Designs</a></li>
<li><a href="#acknowledgements"><span class="toc-section-number">7</span> Acknowledgements</a></li>
</ul>
</div>
<h1 id="introduction"><span class="header-section-number">1</span> Introduction</h1>
<p>A <em>customization point</em>, as will be discussed in this document, is a function used by the Standard Library that can be overloaded on user-defined types in the user’s namespace and that is found by argument-dependent lookup. The Standard Library already defines several customization points:</p>
<ul>
<li><code>swap</code></li>
<li><code>begin</code></li>
<li><code>end</code></li>
</ul>
<p>The first is the most well-known and widely used. It is not obvious that <code>begin</code> and <code>end</code> are in fact customization points until one reads the specification of the range-for statement, which mandates that functions <code>begin</code> and <code>end</code> are called unqualified. (<code>iter_swap</code> may also be a customization point depending on how one chooses to read the specification of the <code>reverse</code> algorithm.) We can expect the number of customization points to grow. For instance, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4017.htm" title="N4014: Non-member size() and more">N4014</a><span class="citation">[2]</span> suggests adding <code>size</code> as a customization point for fetching the size of a range.</p>
<p>The purpose of this paper is to describe some usability problems with the current approach to defining customization points and to suggest a design pattern that can be used when defining future ones.</p>
<h1 id="motivation-and-scope"><span class="header-section-number">2</span> Motivation and Scope</h1>
<p>The correct usage of customization points like <code>swap</code> is to first bring the standard <code>swap</code> into scope with a <code>using</code> declaration, and then to call <code>swap</code> unqualified:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">using</span> std::swap;
swap(a, b);</code></pre>
<p>One problem with this approach is that it is error-prone. It is all too easy to call (qualified) <code>std::swap</code> in a generic context, which is potentially wrong since it will fail to find any user-defined overloads.</p>
<p>Another potential problem – and one that will likely become bigger with the advent of Concepts Lite – is the inability to centralize constraints-checking. Suppose that a future version of <code>std::begin</code> requires that its argument model a <code>Range</code> concept. Adding such a constraint would have no effect on code that uses <code>std::begin</code> idiomatically:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">using</span> std::begin;
begin(a);</code></pre>
<p>If the call to <code>begin</code> dispatches to a user-defined overload, then the constraint on <code>std::begin</code> has been bypassed.</p>
<p>This paper aims to rectify these problems by recommending that future customization points be global function <em>objects</em> that do argument dependent lookup internally on the users’ behalf.</p>
<h2 id="impact-on-the-standard"><span class="header-section-number">2.1</span> Impact on the Standard</h2>
<p>This paper recommends no changes to the current working draft. Changing the definition of existing customization points from function templates to global polymorphic function objects is a potentially breaking change. Users are allowed to add specializations of function templates in namespace <code>std</code> for user-defined types. Such code would be broken by this change.</p>
<p>Rather, this paper proposes merely that any customization points added in the future use the design pattern described below.</p>
<h1 id="proposed-design"><span class="header-section-number">3</span> Proposed Design</h1>
<h2 id="design-goals"><span class="header-section-number">3.1</span> Design Goals</h2>
<p>The goals of customization point design are as follows (for some hypothetical future customization point <code>cust</code>):</p>
<ul>
<li>Code that calls <code>cust</code> either qualified as <code>std::cust(a);</code> or unqualified as <code>using std::cust; cust(a);</code> should behave identically. In particular, it should find any user-defined overloads in the argument’s associated namespace(s).</li>
<li>Code that calls <code>cust</code> as <code>using std::cust; cust(a);</code> should not bypass any constraints defined on <code>std::cust</code>.</li>
<li>Calls to the customization point should be optimally efficient by any reasonably modern compiler.</li>
<li>The solution should not introduce any potential violations of the one-definition rule or excessive executable size bloat.</li>
</ul>
<h2 id="design-details"><span class="header-section-number">3.2</span> Design Details</h2>
<p>This design proposes to make customization points global function objects. Below is what <code>std::begin</code> would look like if it were redesigned as a function object (something this paper does not advocate).</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> std {
  <span class="kw">namespace</span> __detail {
    <span class="co">// define begin for arrays</span>
    <span class="kw">template</span> &lt;<span class="kw">class</span> T, size_t N&gt;
    <span class="kw">constexpr</span> T* begin(T (&amp;a)[N]) <span class="kw">noexcept</span> {
      <span class="kw">return</span> a;
    }

    <span class="co">// Define begin for containers</span>
    <span class="co">// (trailing return type needed for SFINAE)</span>
    <span class="kw">template</span> &lt;<span class="kw">class</span> _RangeLike&gt;
    <span class="kw">constexpr</span> <span class="kw">auto</span> begin(_RangeLike &amp;&amp; rng) -&gt;
      <span class="kw">decltype</span>(forward&lt;_RangeLike&gt;(rng).begin()) {
      <span class="kw">return</span> forward&lt;_RangeLike&gt;(rng).begin();
    }

    <span class="kw">struct</span> __begin_fn {
      <span class="kw">template</span> &lt;<span class="kw">class</span> R&gt;
      <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span>()(R &amp;&amp; rng) <span class="dt">const</span>
        <span class="kw">noexcept</span>(<span class="kw">noexcept</span>(begin(forward&lt;R&gt;(rng)))) -&gt;
        <span class="kw">decltype</span>(begin(forward&lt;R&gt;(rng))) {
        <span class="kw">return</span> begin(forward&lt;R&gt;(rng));
      }
    };
  }

  <span class="co">// To avoid ODR violations:</span>
  <span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
  <span class="kw">constexpr</span> T __static_const{};

  <span class="co">// std::begin is a global function object</span>
  <span class="kw">namespace</span> {
    <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="dt">const</span> &amp; begin =
        __static_const&lt;__detail::__begin_fn&gt;;
  }
}</code></pre>
<p>There are some notable things about this solution. As promised, <code>std::begin</code> is a function object, the type of which is <code>std::__detail::__begin_fn</code>. Also in the <code>std::__detail</code> namespace are the familiar <code>begin</code> free functions which presently live in namespace <code>std</code>. The function call operator of <code>__begin_fn</code> makes an unqualified call to <code>begin</code> which, since it shares the <code>__detail</code> namespace with the <code>begin</code> free functions, will consider those in addition to any overloads that are found by argument-dependent lookup. The strange <code>__static_const</code> template will be described later.</p>
<h2 id="analysis"><span class="header-section-number">3.3</span> Analysis</h2>
<h3 id="qualified-and-unqualified-calls-should-behave-identically"><span class="header-section-number">3.3.1</span> Qualified and unqualified calls should behave identically</h3>
<p>From a behavioral perspective, there are two cases to consider: calling <code>std::begin</code> qualified and calling it unqualified.</p>
<p>It is clear that code that calls <code>std::begin</code> qualified will get the desired behavior. The call routes to <code>__begin_fn::operator()</code>, which makes an unqualified call to <code>begin</code>, thereby finding any user-defined overloads.</p>
<p>In the case that <code>begin</code> is called unqualified after bringing <code>std::begin</code> into scope, the situation is different. In the first phase of lookup, the name <code>begin</code> will resolve to the global object <code>std::begin</code>. Since lookup has found an object and not a function, the second phase of lookup is not performed. In other words, if <code>std::begin</code> is an object, then <code>using std::begin; begin(a);</code> is equivalent to <code>std::begin(a);</code> which, as we’ve already seen, does argument-dependent lookup on the users’ behalf.</p>
<h3 id="unqualified-calls-should-not-bypass-constraints-checking"><span class="header-section-number">3.3.2</span> Unqualified calls should not bypass constraints checking</h3>
<p>Since calls route through the global function object whether calls are made qualified or unqualified, we are sure to get the benefit of any constraints checking done there.</p>
<h3 id="calls-to-the-customization-point-should-be-optimally-efficient"><span class="header-section-number">3.3.3</span> Calls to the customization point should be optimally efficient</h3>
<p>Given the above defintion of <code>std::begin</code> the following program was compiled with GCC 4.9.2 both with and without the USE_CUSTPOINT define (after switching <code>__static_const</code> from a variable template to a class template with a static constexpr data member to get it to compile).</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">int</span> main() {
  <span class="dt">int</span> rgi[] = {<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>};
<span class="ot">#ifdef USE_CUSTPOINT</span>
  <span class="co">// Go through the customization point</span>
  <span class="dt">int</span> * p = std::begin(rgi);
<span class="ot">#else</span>
  <span class="co">// Call the free functions directly</span>
  <span class="kw">using</span> <span class="kw">namespace</span> std::__detail;
  <span class="dt">int</span> * p = begin(rgi);
<span class="ot">#endif</span>
  std::printf(<span class="st">&quot;%p</span><span class="ch">\n</span><span class="st">&quot;</span>,(<span class="dt">void</span>*)p);
}</code></pre>
<p>The resulting optimized (-O3) assembly listings were exactly identical:</p>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="607">
<tr><td><pre>Global object</pre></td><td><pre>Free function</pre></td></tr>
<tr><td valign="top"><pre><code>    .file   "custpnt.cpp"
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
LC0:
    .ascii "%p\12\0"
    .section    .text.startup,"x"
    .p2align 4,,15
    .globl  _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    call    ___main
    leal    16(%esp), %eax
    movl    $LC0, (%esp)
    movl    $1, 16(%esp)
    movl    $2, 20(%esp)
    movl    $3, 24(%esp)
    movl    %eax, 4(%esp)
    movl    $4, 28(%esp)
    call    _printf
    xorl    %eax, %eax
    leave
    ret
    .ident  "GCC: (GNU) 4.9.2"
    .def    _printf;    .scl    2;  .type   32; .endef
</code></pre></td><td><pre><code>   .file   "custpnt.cpp"
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
LC0:
    .ascii "%p\12\0"
    .section    .text.startup,"x"
    .p2align 4,,15
    .globl  _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    call    ___main
    leal    16(%esp), %eax
    movl    $LC0, (%esp)
    movl    $1, 16(%esp)
    movl    $2, 20(%esp)
    movl    $3, 24(%esp)
    movl    %eax, 4(%esp)
    movl    $4, 28(%esp)
    call    _printf
    xorl    %eax, %eax
    leave
    ret
    .ident  "GCC: (GNU) 4.9.2"
    .def    _printf;    .scl    2;  .type   32; .endef
</code></pre></td></tr>
</table>
<p>This makes sense. Although the use of a global reference to a function object would appear to introduce an indirection to every call of the customization point, the body of <code>__begin_fn::operator()</code> is available in every translation unit and does not refer to the implicit <code>this</code> parameter. Therefore, compilers should have no difficulty eliding the parameter, removing the indirection, and inlining the call.</p>
<h3 id="no-violations-of-the-one-definition-rule"><span class="header-section-number">3.3.4</span> No violations of the one-definition rule</h3>
<p>The example code above uses a strange <code>__static_const</code> variable template to avoid ODR violations. The need for it is illustrated by simpler code like below:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="co">// &lt;iterator&gt;</span>
<span class="kw">namespace</span> std {
  <span class="co">// ... define __detail::__begin_fn as before...</span>
  <span class="kw">constexpr</span> __detail::_begin_fn {};
}

<span class="co">// header.h</span>
<span class="ot">#include &lt;iterator&gt;</span>
<span class="kw">template</span> &lt;<span class="kw">class</span> RangeLike&gt;
<span class="dt">void</span> foo( RangeLike &amp; rng ) {
  <span class="kw">auto</span> * pbegin = &amp;std::begin; <span class="co">// ODR violation here</span>
  <span class="kw">auto</span> it = (*pbegin)(rng);
}

<span class="co">// file1.cpp</span>
<span class="ot">#include &quot;header.h&quot;</span>
<span class="dt">void</span> fun() {
  <span class="dt">int</span> rgi[] = {<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>};
  foo(rgi); <span class="co">// INSTANTIATION 1</span>
}

<span class="co">// file2.cpp</span>
<span class="ot">#include &quot;header.h&quot;</span>
<span class="dt">int</span> main() {
  <span class="dt">int</span> rgi[] = {<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>};
  foo(rgi); <span class="co">// INSTANTIATION 2</span>
}</code></pre>
<p>The code above demonstrates the potential for ODR violations if the global <code>std::begin</code> function object is defined naïvely. Both functions <code>fun</code> in file1.cpp and <code>main</code> in file2.cpp cause the implicit instantiation <code>foo&lt;int[4]&gt;</code>. Since global <code>const</code> objects have internal linkage, both translation units file1.cpp and file2.cpp see separate <code>std::begin</code> objects, and the two <code>foo</code> instantiations will see different addresses for the <code>std::begin</code> object. That is an ODR violation.</p>
<p>In contrast, variable templates are required to have external linkage ([temp]/4). Customization points can take advantage of that to avoid the ODR problem, as below:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> std {
  <span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
  <span class="kw">constexpr</span> T __static_const{};
  <span class="kw">namespace</span> {
    <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="dt">const</span>&amp; begin =
      __static_const&lt;__detail::__begin_fn&gt;;
  }
}</code></pre>
<p>Because of the external linkage of variable templates, every translation unit will see the same address for <code>__static_const&lt;__detail::__begin_fn&gt;</code>. Since <code>std::begin</code> is a reference to the variable template, it too will have the same address in all translation units.</p>
<p>The anonymous namespace is needed to keep the <code>std::begin</code> reference itself from being multiply defined. This is from a private communicaiton with James Widman:</p>
<blockquote>
<p>A constexpr reference declared at namespace scope is a variable; but<br />IIUC it has external linkage unless it is placed inside an unnamed<br />namespace.</p>
<p>For objects (not references): a constexpr object implicitly has a<br />const-qualified type, and the added const qualification at namespace<br />scope means that a constexpr object implicitly has internal linkage.</p>
<p>For references: a constexpr reference has no implicitly-added<br />const-qualification on its type. Even if it did, there is nothing in<br />the linkage rules that would implicitly give references internal<br />linkage.</p>
<p>So, it turns out that a constexpr reference at namespace scope would<br />have external linkage by default; so you still want the unnamed<br />namespace.</p>
</blockquote>
<p>The author can imagine a reading of [basic.def.odr]/6 that makes the use of <code>std::begin</code> from multiple translation units an ODR violation. The relevant part of [basic.def.odr]/6.2 is as follows:</p>
<blockquote>
<p>[…] in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), except that a name can refer to a non-volatile const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the object is not odr-used, and the object has the same value in all definitions of D</p>
</blockquote>
<p>The question then comes down to whether the reference <code>std::begin</code> is an <em>entity</em> (which, according to [basic]/3, it is), whether the reference is odr-used in, e.g., inline functions (this is unclear to the author), and what “refer to” means in this context. Does the name <code>std::begin</code> refer to the reference with internal linkage, or to the object referenced with external linkage?</p>
<p>This question was put to core, and the consensus seems to be that this is a defect – or at least that this use case can be supported by a relaxation of [basic.def.odr]/6.2 to “look through” constexpr references (see Mike Miller in c++std-core-27326).</p>
<p>Whether this solution conforms to the letter of the standard as it’s written today, from a purely practical standpoint, it seems patently impossible that the distinction could have any significance to real-world code. It is impossible to get the “address” of a reference entity (as opposed to the address of the object it references), so any template or inline function that uses the <code>std::begin</code> function object is guaranteed to generate identical code in all translation units. And the suggested fix to the ODR specification means this design is likely to conform to the letter of some future version of the standard.</p>
<h3 id="no-executable-bloat"><span class="header-section-number">3.3.5</span> No executable bloat</h3>
<p>If you refer back to the assembly listing for the simple program that uses the <code>std::begin</code> function object, you will notice the lack of any storage for the global objects <code>std::begin</code> or <code>__static_const&lt;__detail::__begin_fn&gt;</code>. The optimizer has removed them. Unoptimized code <em>does</em> have these global objects, but the number of customization points in the STL is so small that their presence in unoptimized object files is not expected to amount to any significant bloat.</p>
<h2 id="hooking-the-customization-point"><span class="header-section-number">3.4</span> Hooking the Customization Point</h2>
<p>End users who wish to “hook” the customization point simply provide the appropriately named overload in their namespace, as they always have.</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> My {
  <span class="kw">struct</span> S {
  };
  <span class="dt">int</span> *begin(S &amp;);
}</code></pre>
<p>Since the global function object performs ADL internally, the overload in the <code>My</code> namespace gets found.</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">int</span> main() {
  My::S s;
  <span class="dt">int</span> *p = std::begin(s); <span class="co">// this calls My::begin</span>
}</code></pre>
<p>As shown, the customization point is hooked by defining a free function of the same name as the global function object. That works well for types in other namespaces but for types that are in <code>std</code> themselves, attempting to define such a free function would lead to an error. So the recommendation for types in <code>std</code> is different. Such types can hook the customization point by defining a friend function, as below:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> std {
  <span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
  <span class="kw">class</span> vector {
  <span class="kw">public</span>:
    <span class="co">// ...</span>
    <span class="kw">friend</span> T * begin(vector &amp; v) {
      <span class="co">// ...</span>
    }
  };
}</code></pre>
<p>(In this case, of course, the friend function is unnecessary since the default <code>begin</code> function automatically works for vectors by calling vector’s <code>begin</code> member function.) Friend functions works for class types. For enums in namespace <code>std</code> that must hook customization points – if any such exist – the recommendation is somewhat less elegant. The enum and the overload must be defined in a hidden namespace, and then the enum is pulled into namespace <code>std</code> with a <code>using</code> declaration, as shown below.</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> std {
  <span class="kw">namespace</span> {
    <span class="co">// If hash were a customization point...</span>
    <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="dt">const</span> &amp; hash =
      __static_const&lt;__detail::__hash_fn&gt;;
  }
  <span class="kw">namespace</span> __hidden {
    <span class="kw">enum</span> memory_order {
      <span class="co">// ...</span>
    };
    <span class="co">// If memory_order needed to hook hash...</span>
    size_t hash(memory_order) {
      <span class="co">// ...</span>
    }
  }
  <span class="kw">using</span> __hidden::memory_order;
}</code></pre>
<p>Although ugly this would work, and it would only be needed should an enum in namespace std ever need to hook a customization point, which seems unlikely.</p>
<h1 id="design-drawbacks"><span class="header-section-number">4</span> Design Drawbacks</h1>
<p>The author is aware of a few relatively minor drawbacks to the approach described here. The first is added complexity of implementing and specifying customization points. That could be alleviated by centrally defining <em>customization point</em> as a term of art in the standard – describing the properties of customization points instead of the implementation details – and then saying which APIs are customization points.</p>
<p>Another drawback is the added complexity from the perspective of end users. Although this design doesn’t change how people hook the customization point[*] or necessitate changes in how they are called, it will require users to understand what’s going on when things break. It also may not be obvious that a qualified call to a function <code>std::foo</code> will find a <code>foo</code> function in another namespace. This is somewhat mitigated by the fact that users can continue doing <code>using std::foo; foo(a);</code> as they have been told to do for years.</p>
<p>This design may also negatively impact compiler error messages when the customization point is misused. Since the call redirects though an intermediate function object, there will necessary be more noise in the compiler backtrace. This problem is likely to go away with Concepts Lite.</p>
<p>Unoptimized builds will get somewhat slower and larger with this change, but it’s unlikely to be enough to be noticed.</p>
<p>There would also necessarily be some inconsistency in the standard if we accepted this new design for future customization points but left the existing ones alone. That hardly seems a reason to the author to continue doing things in a sub-standard way if the committee decides that the new approach is better. An alternate approach that would not introduce inconsistency would be to adopt the new design for any future TS to redesign the STL as has been discussed in the context of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4377.pdf" title="N4377: Programming Languages — C++ Extensions for Concepts">Concepts Lite</a><span class="citation">[5]</span> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html" title="N4128: Ranges for the Standard Library, Revision 1">Ranges</a><span class="citation">[3]</span>.</p>
<p>A more concerning issues comes from James Widman, who points out that defining customization points as objects can introduce ambiguity errors where none would otherwise occur. See the example below:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iterator&gt; </span><span class="co">// for std::begin function object</span>

<span class="co">// begin user&#39;s code:</span>

<span class="kw">struct</span> X{};
<span class="dt">void</span> begin(X);

<span class="kw">using</span> <span class="kw">namespace</span> std;

<span class="dt">void</span> g() {
  begin(X()); <span class="co">// error: ambiguous name lookup result: &#39;::begin&#39;</span>
              <span class="co">// (function) and &#39;std::begin&#39; (reference-to-object)</span>
}</code></pre>
<p>The ambiguity occurs when the user:</p>
<ul>
<li>Defines a free function with the same name as a standard customization point.</li>
<li>Imports the <code>std</code> namespace with a using directive.</li>
<li>Makes an unqualified call to the function.</li>
</ul>
<p>In that case, lookup will find both the function and the object and error out. This is cause for legitimate concern. The mitigating factors are:</p>
<ul>
<li>It is an error at compile time, not a silent breakage.</li>
<li>The problem is solvable by explicitly qualifying the call.</li>
<li>Defining a free function of the same name as a standard customization point without intending to hook the customization point is dubious practice, in this author’s opinion.</li>
<li>Making an unqualified call to a free function with the same name as a standard customization point, expecting yours to be chosen by name lookup/overload resolution, is also dubious practice, in this author’s opinion.</li>
</ul>
<p>Whether these mitigating factors are enough is left for the committee to decide.</p>
<p>[*] This design does not permit users to hook customization points by specializing function templates in namespace <code>std</code>. If users are accustomed to doing that, they will need to learn new behavior. But in the opinion of the author, they should anyway.</p>
<h1 id="implementation-experience"><span class="header-section-number">5</span> Implementation Experience</h1>
<p>The customization point design recommended here has been used for the past year in the <a href="https://github.com/ericniebler/range-v3" title="Range v3">Range-v3</a><span class="citation">[4]</span> library, where <em>all</em> functions are implemented as global function object, not just the customization points. The library is popular judging from the number of people who have registered for notifications, cloned it, and submitted issues and pull requests. There have thus far been no negative comments from users about the use of global function objects or about the customization point design.</p>
<p>Admittedly, this experience is limited.</p>
<h1 id="alternative-designs"><span class="header-section-number">6</span> Alternative Designs</h1>
<p>One alternative is to not change anything. The approach to customization point design that the current standard takes – namely, just making them free functions and requiring <code>using</code> declarations to call them – has served the community with some degree of success since the beginning. The drawbacks of this approach have already been described.</p>
<p>Another approach is to replace the function <em>object</em> described here with a free function that dispatches to a differently named function. For instance, a <code>std::begin</code> free function could make an unqualified call to a free function named <code>std_begin</code>, as below:</p>
<pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> std {
  <span class="co">// define begin for arrays</span>
  <span class="kw">template</span> &lt;<span class="kw">class</span> T, size_t N&gt;
  <span class="kw">constexpr</span> T* std_begin(T (&amp;a)[N]) <span class="kw">noexcept</span> {
    <span class="kw">return</span> a;
  }

  <span class="co">// Define begin for containers</span>
  <span class="co">// (trailing return type needed for SFINAE)</span>
  <span class="kw">template</span> &lt;<span class="kw">class</span> _RangeLike&gt;
  <span class="kw">constexpr</span> <span class="kw">auto</span> std_begin(_RangeLike &amp;&amp; rng) -&gt;
    <span class="kw">decltype</span>(forward&lt;_RangeLike&gt;(rng).begin()) {
    <span class="kw">return</span> forward&lt;_RangeLike&gt;(rng).begin();
  }

  <span class="kw">template</span> &lt;<span class="kw">class</span> R&gt;
  <span class="kw">constexpr</span> <span class="kw">auto</span> begin(R &amp;&amp; rng) -&gt;
    <span class="kw">decltype</span>(std_begin(forward&lt;R&gt;(rng))) {
    <span class="kw">return</span> std_begin(forward&lt;R&gt;(rng));
  }
}</code></pre>
<p>Users hook customization points like this by overloaded <code>std_begin</code> in their namespace. They call <code>std::begin</code> qualified. This design is certainly more straightforward than the design presented here. It is used in <a href="http://boost.org/libs/range" title="Boost.Range">Boost.Range</a><span class="citation">[1]</span>, where <code>boost::begin</code> makes an unqualified call to a <code>range_begin</code> function that users can overload.</p>
<p>The problems with this approach are:</p>
<ul>
<li>It make current practice of calling customization points unqualified after a <code>using</code> declaration wrong. With this approach, ADL shouldn’t be happening on the name “<code>begin</code>” – it should happen only on the name “<code>std_begin</code>”.</li>
<li>It makes it unclear how to hook the customization point. Do users overload <code>begin</code> or <code>std_begin</code>? Or do they specialize <code>begin</code> in namespace <code>std</code>? All will work to one degree or another, but only one is “correct”.</li>
</ul>
<p>Finally, a third approach would be to add a new language feature for customization points that would achieve the desired goals without the drawbacks. This solution has not yet been pursued. The author hopes that a pure library solution is good enough.</p>
<h1 id="acknowledgements"><span class="header-section-number">7</span> Acknowledgements</h1>
<p>The author would like to thank James Widman for reviewing an early version of this paper, offering feedback and explaining the intricacies of lookup and the ODR as they relate to this proposal.</p>
<div class="references">
<h1>References</h1>
<p>[1]Boost.Range Library: <em><a href="http://boost.org/libs/range" class="uri">http://boost.org/libs/range</a></em>. Accessed: 2014-10-08.</p>
<p>[2]Marcangelo, R. 2014. N4017: Non-member size() and more.</p>
<p>[3]Niebler, E. et al. 2014. N4128: Ranges for the Standard Library, Revision 1.</p>
<p>[4]Range v3: <em><a href="https://github.com/ericniebler/range-v3" class="uri">https://github.com/ericniebler/range-v3</a></em>. Accessed: 2014-10-08.</p>
<p>[5]2015. N4377: Programming Languages — C++ Extensions for Concepts.</p>
</div>
</body>
</html>
