<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Improving Pair and Tuple (Revision 2)</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  blockquote.note
  {
   background-color:#E0E0E0;
   padding-left: 15px;
   padding-right: 15px;
   padding-top: 1px;
   padding-bottom: 1px;
  }
</style>
</head><body>
<address style="text-align: left;">
Document number: N4064<br>
Date: 2014-07-02<br>
Revises: N3739<br>
Author: Daniel Kr&uuml;gler<br>
Project: Programming Language C++, Library Working Group<br>
Reply-to: <a href="mailto:daniel.kruegler@gmail.com">Daniel Kr&uuml;gler</a>
</address>
<hr>
<h1 style="text-align: center;">Improving <tt>pair</tt> and <tt>tuple</tt>, revision 2</h1>
<p>
<strong>Addressed issues</strong>: 
</p>
<ul>
<li><p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2051">LWG 2051</a>.
</p></li>
<li><p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2397">LWG 2397</a>.
</p></li>
<li><p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2312">LWG 2312</a> is <em>partially</em> addressed: The currently 
proposed wording still intends to make an implementation conforming that would accept a smaller number of elements values compared to the
actual tuple-size (and to value-initialize the remaining ones), therefore the size-related requirements are currently not part of the
SFINAE constraints. If LWG 2312 would be accepted the corresponding constraints would be similarly adjusted as described by the issue 
and the corresponding requirement could be removed.
</p></li>
</ul>
<p>
<h2><a name="RevisionHistory"></a>Revision History</h2>
<p>
Changes since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3739.html">N3739</a> (revision 1):
</p>
<ul>
<li><p>Improved the current rationale (Thanks to Mike Spertus!)</p>
</li>
<li><p>During the Rapperswil LEWG discussion a new vote lead to a revised result on the preferred
representation form:</p>
<blockquote>
<p>
Do we prefer the <tt><i>EXPLICIT(see below)</i> constexpr tuple(UTypes&amp;&amp;...);</tt> editorial representation?
<p/>
SF-F-N-A-SA
<p/>
0-8-3-2-0
</p>
</blockquote>
<p>Therefore this revision now uses the annotation <tt><i>EXPLICIT</i></tt> for the affected constructor pairs
and defines the meaning of that in Clause 17.</p>
</li>
</ul>

<p>
Changes since <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3680.html">N3680</a>:
</p>
<ul>
<li><p>
During a straw-pool vote there was a small majority (4:3) in favour for keeping the two-signatures approach,
so this presentation form was used in this revision.
</p></li>
<li><p>
The original example has been improved.
</p></li>
<li><p>
The missing application of the declaration pattern to the <tt>allocator_arg_t</tt> constructors has been fixed.
</p></li>
<li><p>
Consequent usage of the more precise <tt>is_convertible</tt> trait instead of the somewhat vague 
<em>is implicitly convertible</em> description.
</p></li>
</ul>
<h2><a name="Introduction"></a>Introduction</h2>
<p>
For many programmers it is a surprise to find out, that the following code is rejected by their compiler:
</p>
<blockquote><pre>
std::tuple&lt;int, int&gt; pixel_coordinates() 
{
  return {10, -15};  <span style="color:#C80000;font-weight:bold">// Oops: Error</span>
}

struct NonCopyable { NonCopyable(int); NonCopyable(const NonCopyable&amp;) = delete; };

std::pair&lt;NonCopyable, double&gt; pmd{42, 3.14};  <span style="color:#C80000;font-weight:bold">// Oops: Error</span>
</pre></blockquote>

<p>
<strong>What is wrong with this? Why doesn't this just work?</strong>
<p/>
This paper explains the reason for the current specification of <tt>pair</tt> and <tt>tuple</tt> and suggests
changes to the working paper to fix these and some other bothersome constraints of these general type wrappers.
</p>

<h2><a name="History"></a>Looking backwards</h2>
<p>
At the time when <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3140.html">N3240</a> was
proposed, several driving forces defined the constraints of resolving a bunch of library issues and NB 
comments.
<p/>
One notable intention was to prevent that the type wrappers <tt>tuple</tt> and <tt>pair</tt> should allow
implicit conversions for wrapped types that are not implicitly convertible, as expressed by 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#1324">LWG 1324</a> and
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#DE15">DE 15</a>.
<p/>
Another relevant requirement was to keep backward-compatibility to C++03 in regard to null pointer literals
expressed as integral null constants as described by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#811">LWG 811</a>.
<p/>
At that time there was a strong resistance to add further constructors especially to <tt>std::pair</tt>. At some point in
time there did exist a very large number of such constructors due to allocator support. One important consequence 
of this pair simplification was the acceptance of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3059.pdf">N3059</a>.
<p/>
Thus with the previous acceptance of proposal <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3140.html">N3240</a>
the specification provides the following <strong>advantages</strong> for <tt>pair</tt> and <tt>tuple</tt>:
<p>
<ol>
<li><p>
Heterogenous template constructors are constrained upon the criterion that the element-wise source types are 
<em>implicitly convertible</em> to the element-wise destination types.
</p>
<blockquote><pre>
struct B { explicit B(bool); };

std::tuple&lt;B&gt; tb = std::tuple&lt;bool&gt;(); <span style="color:#006600;font-weight:bold">// Error</span>
</pre></blockquote>
</li>
<li><p>
The non-template constructor <tt>tuple(const Types&amp;...)</tt> and the corresponding template-constructor are 
<em>explicit</em>. This prevents that a single-element tuple from being <strong>copy-initialized</strong> by an 
argument object and has only an <em>explicit</em> constructor for this construction.
</p>
<blockquote><pre>
struct X { X(); explicit X(const X&amp;); } x;

std::tuple&lt;X&gt; tx = x; <span style="color:#006600;font-weight:bold">// Error</span>

struct E { explicit E(int); };

std::tuple&lt;E&gt; te = 42; <span style="color:#006600;font-weight:bold">// Error</span>
</pre></blockquote>
</li>
<li><p>
Non-template constructors accepting a sequence of elements, such as <tt>explicit tuple(const Types&amp;...)</tt>
and <tt>pair(const T1&amp; x, const T2&amp; y)</tt>, are still kept to support the special conversion scenario where a 
pointer(-to-member) element type is initialized with the <strong>null pointer constant <tt>0</tt></strong> instead of <tt>nullptr</tt>.
</p>
<blockquote><pre>
class C;

std::tuple&lt;int*&gt; tpi(0); <span style="color:#006600;font-weight:bold">// OK</span>
std::tuple&lt;int C::*&gt; tpmi(0); <span style="color:#006600;font-weight:bold">// OK</span>
</pre></blockquote>
</li>
</ol>

<h2><a name="Discussion"></a>Discussion</h2>
<p>
We propose that <tt>pair</tt>/<tt>tuple</tt> obey the same initialization rules as their underlying element types. Unless we have 
such "perfect initialization", <tt>pair</tt> and <tt>tuple</tt> exhibit confusing and unintuitive behavior as illustrated 
by the examples below.
</p>
<ol>
<li>
<p/>
It means that <tt>tuple</tt> objects cannot be <em>returned</em> from a function as simple as this:
</p>
<blockquote><pre>
std::tuple&lt;int, int&gt; foo_tuple() 
{
  return {1, -1};  <span style="color:#C80000;font-weight:bold">// Error</span>
}

std::pair&lt;int, int&gt; foo_pair() 
{
  return {1, -1};  <span style="color:#006600;font-weight:bold">// OK</span>
}
</pre></blockquote>
</li>

<li>
<p/>
It means that <tt>tuple</tt> or <tt>pair</tt> objects cannot be <em>constructed</em> for element types that cannot be copied:
</p>
<blockquote><pre>
struct D { D(int); D(const D&amp;) = delete; };

std::tuple&lt;D&gt; td(12); <span style="color:#C80000;font-weight:bold">// Error</span>
</pre></blockquote>
</li>

<li>
<p/>
It even means that <tt>tuple</tt> or <tt>pair</tt> objects cannot be <em>direct-constructed</em> for element types via an explicit 
conversion:
</p>
<blockquote><pre>
struct Y { explicit Y(int); };

std::tuple&lt;Y&gt; ty(12); <span style="color:#C80000;font-weight:bold">// Error</span>
</pre></blockquote>
</li>

<li>
<p>
It has been observed by <a href="http://stackoverflow.com/questions/11386042/confused-by-default-constructor-description-of-stdtuple-in-the-iso-c-standar">Johannes Schaub</a> 
that there exists a defect with <tt>tuple</tt> in regard to the 
non-template constructor <tt>explicit tuple(const Types&amp;...)</tt>: The current specification has the effect that
the instantiation of <tt>tuple&lt;&gt;</tt> would be required to be ill-formed because it has two conflicting default 
constructors.
</p>
</li>
</ol>

<p>Starting with the last point: This is indeed a simple oversight that slipped in during the <tt>tuple</tt> standardization. 
The <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</a> document did have the following specification:</p>
<blockquote><pre>
template &lt;class T1 = <em>unspecified</em> ,
          class T2 = <em>unspecified</em> ,
          ...,
          class TM = <em>unspecified</em> &gt;
class tuple
{
public:
  tuple();
  explicit tuple(P1, P2, ..., PN); <em><span style="color:black;font-weight:bold">// iff N &gt; 0</span></em>
  [&hellip;]
};
</pre></blockquote>

<p>When the variadic form of tuples was proposed via <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2151.pdf">N2151</a>
and its successors, the highlighted size constraint inadvertently got lost.</p>

<p>The other three problems are all caused by (A) constructors that are always <em>explicit</em> and (B) by constrained constructor
templates that impose <em>implicit convertible</em> constraints on the element types.</p>

<p>So, notwithstanding the good motivation behind the current specification of <tt>pair</tt> and <tt>tuple</tt>, it turns out to have
some unfortunate consequences. 
</p>

<p>This proposal is intending to solve all these problems by a simple procedure that still ensures that all positive aspects of the current
specification are conserved.</p>

<h2><a name="perfect_init"></a>"Perfect initialization"</h2>
<p>
Before explaining the general outline of this proposal it is more helpful to start with a simple, but useful programming idiom. 
<p/>
Consider the following class template <tt>A</tt> that is intended to be used as a wrapper for some other type <tt>T</tt>:
</p>
<blockquote><pre>
#include &lt;type_traits&gt;
#include &lt;utility&gt;

template&lt;class T&gt;
struct A {
  template&lt;class U,
    typename std::enable_if&lt;
      <span style="color:#3399FF;font-weight:bold">std::is_constructible&lt;T, U&gt;::value &amp;&amp;</span>
      <span style="color:#3399FF;font-weight:bold">std::is_convertible&lt;U, T&gt;::value</span>
    , bool&gt;::type = false
  &gt;
  A(U&amp;&amp; u) : t(std::forward&lt;U&gt;(u)) {}

 template&lt;class U,
    typename std::enable_if&lt;
      <span style="color:#3399FF;font-weight:bold">std::is_constructible&lt;T, U&gt;::value &amp;&amp;</span>
      <span style="color:#3399FF;font-weight:bold">!std::is_convertible&lt;U, T&gt;::value</span>
    , bool&gt;::type = false
  &gt;
  explicit A(U&amp;&amp; u) : t(std::forward&lt;U&gt;(u)) {}
  
  T t;
};
</pre></blockquote>

<p>
The shown constructors both use <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html">perfect forwarding</a>
and they have essentially the same signatures except for one being explicit, the other one not. Furthermore, they are
<em>mutually exclusively</em> constrained. In other words: This combination behaves for any destination type <tt>T</tt> and any 
argument type <tt>U</tt> like a <em>single</em> constructor that is <strong>either explicit or non-explicit</strong> (or no constructor
at all). Attempts to construct a <tt>A&lt;T&gt;</tt> from some value of type <tt>U</tt> will reflect the allowed initialization forms 
of the wrapped type <tt>T</tt>:
</p>

<blockquote><pre>
struct Im{ Im(int){} };
struct Ex{ explicit Ex(int){} };

A&lt;Im&gt; ai1(1); // OK
A&lt;Im&gt; ai2{2}; // OK

A&lt;Im&gt; ai3 = 3;   // OK
A&lt;Im&gt; ai4 = {4}; // OK

A&lt;Ex&gt; ae1(1); // OK
A&lt;Ex&gt; ae2{2}; // OK

A&lt;Ex&gt; ae3 = 3;   // Error
A&lt;Ex&gt; ae4 = {4}; // Error
</pre></blockquote>

<p>
This technique can easily be extended to the variadic template case, and when doing so can be considered as a key to solving
the problems of <tt>tuple</tt> and <tt>pair</tt>.

<p/>
It should be noted here, that for the general case the <tt>std::is_constructible&lt;T, U&gt;::value</tt> requirement for the
non-explicit constructor which is constrained on <tt>std::is_convertible&lt;U, T&gt;::value</tt> is not redundant, because it
is possible to create types that can be copy-initialized but not direct-initialized:
</p>
<blockquote><pre>
struct Odd {
  explicit Odd(int) = delete;
  Odd(long){}
};

Odd o2 = 1; // OK
Odd o1(1);  // Error
</pre></blockquote>

<p>
Technically it would be possible to apply the same technique of creating element-dependent explicit or non-explicit default
constructors. This application was shortly considered during the write-up of this proposal, but rejected because for the 
current C++ rules there is no longer any observable difference for an <tt>explicit</tt>  default constructor that cannot be 
invoked with more than zero arguments and one that is not <tt>explicit</tt>.
<p/>
The technique cannot be applied to copy/move operators in the same way as for the other constructors (because these special
member functions cannot be templates) and given the very rare request for such a support the idea was no further investigated 
by the author. A second argument against providing this support is based on the consistency with the core language rules
that the <tt>explicit</tt>-character of these constructors is not conserved for the implicitly declared versions in classes 
that contain corresponding sub-objects with such explicit constructors. 
</p>

<h2><a name="Outline"></a>Outline</h2>

<p>
As shown above, the current over-constraining restrictions of the <tt>pair</tt> and <tt>tuple</tt> constructors are due to
unconditional usage of <em>explicit</em> and <em>implicitly convertible</em> requirements.
<p/>
The general approach of this proposal is to require "perfect initialization" semantics for <tt>pair</tt> and <tt>tuple</tt> 
constructors extended to the variadic case. Albeit this seemingly doubles the number of constructor declarations in the draft, 
it does not change the <em>effective</em> number of these for a particular combination of element type and source type of 
some initialization due to their mutual exclusion property. 
<p/>
In theory the same technique could be applied to the <tt>piecewise_construct_t</tt> of <tt>pair</tt>. This proposal does 
not propose this, because this constructor is specifically asked for by the corresponding tag and there are no further
constraint except the <tt>is_constructible</tt> requirements.
<p/>
In addition, this proposal fixes the specification problem of <tt>tuple&lt;&gt;</tt>'s default constructors.
<p/>
The wording is intentionally chosen, so that an implementation is not required (but allowed) to use the "perfect initialization" idiom.
<p/>
This is done by taking advantage of the already existing nomenclature "This function does not participate in overload resolution 
unless [&hellip;]". Its worth emphasizing that even though this phrase is usually used to describe constrained templates 
in the Library specification, the actual wording of this doesn't necessarily imply to "sfinae out" template functions. Many library 
implementations solve this problem by providing a specialization for the empty <tt>tuple</tt> case that does not provide 
the additional default constructor, for example. This is also a valid way to ensure that functions don't participate in overload resolution.
</p>

<h2><a name="WhyNotExplicitSingleArgs"></a>Why not explicit for single argument constructors only?</h2>
<p>
In C++03 <tt>explicit</tt> constructors had no behavioural difference, unless they had been single-argument constructors, so
one might suggest to restrict adding the <tt>explicit</tt> keyword to constructors that take exactly one argument.
<p/>
I think this is idea is flawed (unless I'm using specifically tagged constructors like the piecewise-one of <tt>pair</tt>). Consider 
the following example:
</p>
<blockquote><pre>
#include &lt;tuple&gt;
#include &lt;chrono&gt;
#include &lt;iostream&gt;

using hms_t = std::tuple&lt;std::chrono::hours, std::chrono::minutes, std::chrono::seconds&gt;;

void launch_rocket_at(std::chrono::seconds s)
{
  std::cout &lt;&lt; "launching rocket in " &lt;&lt; s.count() &lt;&lt; " seconds!\n";
}

void launch_rocket_at(hms_t times)
{
  using namespace std;
  launch_rocket_at(get&lt;0&gt;(times) + get&lt;1&gt;(times) + get&lt;2&gt;(times));
}

int main()
{
  using namespace std;
  <span style="color:#C80000;font-weight:bold">launch_rocket_at(make_tuple(1, 2, 3)); // #1: very scary</span>
  <span style="color:#C80000;font-weight:bold">launch_rocket_at({1, 2, 3});           // #2: even scarier</span>
  using namespace std::chrono;
  <span style="color:#006600;font-weight:bold">launch_rocket_at(make_tuple(hours(1), minutes(2), seconds(3))); // #3: Perfectly clear!</span>
  <span style="color:#006600;font-weight:bold">launch_rocket_at({hours(1), minutes(2), seconds(3)});           // #4: Also clear!</span>
  <span style="color:#006600;font-weight:bold">launch_rocket_at(hms_t{1, 2, 3});                               // #5: And this, too</span>
}
</pre></blockquote>

<p>
which should output:
</p>

<blockquote><pre>
launching rocket in 3723 seconds!
launching rocket in 3723 seconds!
launching rocket in 3723 seconds!
</pre></blockquote>

<p>
If the former two calls to function <tt>launch_rocket_at</tt> where possible, this would directly subvert the
intended explicitness of the <tt>std::duration</tt> constructor and would make using the time-utility
types much more unsafe. Why? Consider the following scenario:
<p/>
If the client believed that the order of the units was <em>seconds, minutes, hours</em>, and input 3, 2, 1, &mdash; 
intending 3 seconds, 2 minutes, and 1 hour &mdash; the rocket would launch in 10,921 seconds instead of the intended 
3,723 seconds. This mistake can indeed easily happen, if you look again at the lines marked with <b>#1</b> and  <b>#2</b>.
<p/>
Due to our intentionally conserved constraints to be explicit here we catch that mistake at compile-time, 
instead of having to shoot the rocket down...
</p>

<h2><a name="WordingForm"></a>Editorial Representation</h2>
<p>
During the write-up of this proposal I had the idea of replacing the prototype declaration pairs by
a single one expressed by some pseudo-macro that looks like a single declaration. For example
</p>
<blockquote><pre>
template &lt;class... UTypes&gt;
constexpr tuple(UTypes&amp;&amp;...);
template &lt;class... UTypes&gt;
explicit constexpr tuple(UTypes&amp;&amp;...);
</pre></blockquote>

<p>could instead be declared as follows:</p>

<blockquote><pre>
template &lt;class... UTypes&gt;
<i>EXPLICIT</i> constexpr tuple(UTypes&amp;&amp;...);
</pre></blockquote>

<p>This form of representation still means that <tt><i>EXPLICIT</i></tt> needs to be defined somewhere
and somehow, but only once. 
<p/>
There was a strong preference during the Rapperswil 2014 LEWG discussion to use the 
"macro" instead of the individual declarations.
<p/>
This paper does not use a previously suggested form of <tt><i>EXPLICIT(see below)</i></tt> instead of <tt><i>EXPLICIT</i></tt>, 
because there is nothing specific to explain below again (The different SFINAE conditions are not relevant at that point,
because they appear as usual with the normal, detailed prototype specifications).
<p/>
In any way, the final editorial decision is being handed over to the project editor.
</p>

<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
The proposed wording changes refer to <a href="http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n3936.pdf">N3936</a>.
</p>
<ol>
<li><p>Insert the following new sub-clause immediately following 17.5.2.3 [objects.within.classes]
as a further children of 17.5.2 [conventions]:</p>

<p><ins><b><tt><i>EXPLICIT</i></tt> constructors</b> [explicit.within.classes]</ins></p>
<blockquote>
<p><ins>-?- For the sake of exposition, the library clauses sometimes annotate constructors with <tt><i>EXPLICIT</i></tt>. 
For every constructor declaration that contains <tt><i>EXPLICIT</i></tt>, the meaning is equivalent to two consecutive 
declarations of exactly the same members, except that one of these two members has the <tt><i>EXPLICIT</i></tt> removed
and the other one is declared with a <i>function-specifier</i> <tt>explicit</tt> instead of <tt><i>EXPLICIT</i></tt>.</ins>
</p>

</blockquote>
</li>

<li>
<p>Change 20.3.2 [pairs.pair], class template <tt>pair</tt> synopsis, as indicated:</p>
<blockquote>
<pre>
namespace std {
  template &lt;class T1, class T2&gt;
  struct pair {
    typedef T1 first_type;
    typedef T2 second_type;

    T1 first;
    T2 second;
    pair(const pair&amp;) = default;
    pair(pair&amp;&amp;) = default;
    constexpr pair();
    <ins><i>EXPLICIT</i></ins> constexpr pair(const T1&amp; x, const T2&amp; y);
    template&lt;class U, class V&gt; <ins><i>EXPLICIT</i></ins> constexpr pair(U&amp;&amp; x, V&amp;&amp; y);
    template&lt;class U, class V&gt; <ins><i>EXPLICIT</i></ins> constexpr pair(const pair&lt;U, V&gt;&amp; p);
    template&lt;class U, class V&gt; <ins><i>EXPLICIT</i></ins> constexpr pair(pair&lt;U, V&gt;&amp;&amp; p);
    template &lt;class... Args1, class... Args2&gt;
    pair(piecewise_construct_t,
      tuple&lt;Args1...&gt; first_args, tuple&lt;Args2...&gt; second_args);

    pair&amp; operator=(const pair&amp; p);
    template&lt;class U, class V&gt; pair&amp; operator=(const pair&lt;U, V&gt;&amp; p);
    pair&amp; operator=(pair&amp;&amp; p) noexcept(<em>see below</em>);
    template&lt;class U, class V&gt; pair&amp; operator=(pair&lt;U, V&gt;&amp;&amp; p);

    void swap(pair&amp; p) noexcept(<em>see below</em>);
  };
}
</pre>
</blockquote>
</li>
<li><p>Change 20.3.2 [pairs.pair] around p5 as indicated:</p>
<blockquote><pre>
<ins><i>EXPLICIT</i></ins> constexpr pair(const T1&amp; x, const T2&amp; y);
</pre><blockquote>
<p>
<del>-5- <em>Requires</em>: <tt>is_copy_constructible&lt;first_type&gt;::value</tt> is <tt>true</tt> and 
<tt>is_copy_constructible&lt;second_type&gt;::value</tt> is <tt>true</tt>.</del>
<p/>
-6- <em>Effects</em>: The constructor<ins>s</ins> initialize<del>s</del> <tt>first</tt> with <tt>x</tt> and <tt>second</tt> with <tt>y</tt>.
<p/>
<ins>-?- <em>Remarks</em>: The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_copy_constructible&lt;first_type&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_copy_constructible&lt;second_type&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const first_type&amp;, first_type&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_convertible&lt;const second_type&amp;, second_type&gt;::value</tt> is <tt>true</tt></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_copy_constructible&lt;first_type&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_copy_constructible&lt;second_type&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const first_type&amp;, first_type&gt;::value</tt> is <tt>false</tt> or 
	<tt>is_convertible&lt;const second_type&amp;, second_type&gt;::value</tt> is <tt>false</tt></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>

<li><p>Change 20.3.2 [pairs.pair] around p7 as indicated:</p>
<blockquote><pre>
template&lt;class U, class V&gt; <ins><i>EXPLICIT</i></ins> constexpr pair(U&amp;&amp; x, V&amp;&amp; y);
</pre><blockquote><p>
<del>-7- <em>Requires</em>: <tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>.</del>
<p/>
-8- <em>Effects</em>: The constructor<ins>s</ins> initialize<del>s</del> <tt>first</tt> with <tt>std::forward&lt;U&gt;(x)</tt> and <tt>second</tt> with 
<tt>std::forward&lt;V&gt;(y)</tt>.
<p/>
-9- <em>Remarks</em>: <del>If <tt>U</tt> is not implicitly convertible to <tt>first_type</tt> or <tt>V</tt> is not implicitly convertible to 
  <tt>second_type</tt> this constructor shall not participate in overload resolution.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;U&amp;&amp;, first_type&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_convertible&lt;V&amp;&amp;, second_type&gt;::value</tt> is <tt>true</tt></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;U&amp;&amp;, first_type&gt;::value</tt> is <tt>false</tt> or 
	<tt>is_convertible&lt;V&amp;&amp;, second_type&gt;::value</tt> is <tt>false</tt></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>

<li><p>Change 20.3.2 [pairs.pair] around p10 as indicated:</p>
<blockquote><pre>
template&lt;class U, class V&gt; <ins><i>EXPLICIT</i></ins> constexpr pair(const pair&lt;U, V&gt;&amp; p);
</pre><blockquote><p>
<del>-10- <em>Requires</em>: <tt>is_constructible&lt;first_type, const U&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, const V&amp;&gt;::value</tt> is <tt>true</tt>.</del>
<p/>
-11- <em>Effects</em>: <ins>The constructors initialize</ins><del>Initializes</del> members from the corresponding members of the argument.
<p/>
-12- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless <tt>const U&amp;</tt> is 
    implicitly convertible to <tt>first_type</tt> and <tt>const V&amp;</tt> is implicitly convertible to <tt>second_type</tt>.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;first_type, const U&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, const V&amp;&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const U&amp;, first_type&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_convertible&lt;const V&amp;, second_type&gt;::value</tt> is <tt>true</tt></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;first_type, const U&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, const V&amp;&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const U&amp;, first_type&gt;::value</tt> is <tt>false</tt> or 
	<tt>is_convertible&lt;const V&amp;, second_type&gt;::value</tt> is <tt>false</tt></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>
<li><p>Change 20.3.2 [pairs.pair] around p13 as indicated:</p>
<blockquote><pre>
template&lt;class U, class V&gt; <ins><i>EXPLICIT</i></ins> constexpr pair(pair&lt;U, V&gt;&amp;&amp; p);
</pre><blockquote><p>
<del>-13- <em>Requires</em>: <tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>.</del>
<p/>
-14- <em>Effects</em>: The constructor<ins>s</ins> initialize<del>s</del> <tt>first</tt> with <tt>std::forward&lt;U&gt;(p.first)</tt> 
and <tt>second</tt> with <tt>std::forward&lt;V&gt;(p.second)</tt>.
<p/>
-15- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless <tt>U</tt> is 
implicitly convertible to <tt>first_type</tt> and <tt>V</tt> is implicitly convertible to <tt>second_type</tt>.</del>
<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;U&amp;&amp;, first_type&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_convertible&lt;V&amp;&amp;, second_type&gt;::value</tt> is <tt>true</tt></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;U&amp;&amp;, first_type&gt;::value</tt> is <tt>false</tt> or 
	<tt>is_convertible&lt;V&amp;&amp;, second_type&gt;::value</tt> is <tt>false</tt></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>

<li><p>Change 20.4.2 [tuple.tuple], class template <tt>tuple</tt> synopsis, as indicated. The intent is to declare
the set of <em>"conditionally explicit"</em> constructors and to fix the <em>multiple default constructor</em>
problem for empty tuples.</p>
<blockquote><pre>
namespace std {
  template &lt;class... Types&gt;
  class tuple {
  public:
    // 20.4.2.1, tuple <em>construction</em>
    constexpr tuple();
    <ins><i>EXPLICIT</i></ins><del>explicit</del> constexpr tuple(const Types&amp;...); <ins><em>// only if</em> sizeof...(Types) &gt;= 1</ins>
    template &lt;class... UTypes&gt;
      <ins><i>EXPLICIT</i></ins><del>explicit</del> constexpr tuple(UTypes&amp;&amp;...);   <ins><em>// only if</em> sizeof...(Types) &gt;= 1</ins>
    
    tuple(const tuple&amp;) = default;
    tuple(tuple&amp;&amp;) = default;
  
    template &lt;class... UTypes&gt;
      <ins><i>EXPLICIT</i></ins> constexpr tuple(const tuple&lt;UTypes...&gt;&amp;);
    template &lt;class... UTypes&gt;
      <ins><i>EXPLICIT</i></ins> constexpr tuple(tuple&lt;UTypes...&gt;&amp;&amp;);

    template &lt;class U1, class U2&gt;
      <ins><i>EXPLICIT</i></ins> constexpr tuple(const pair&lt;U1, U2&gt;&amp;);          <em>// only if</em> sizeof...(Types) == 2
    template &lt;class U1, class U2&gt;
      <ins><i>EXPLICIT</i></ins> constexpr tuple(pair&lt;U1, U2&gt;&amp;&amp;);               <em>// only if</em> sizeof...(Types) == 2

    <em>// allocator-extended constructors</em>
    template &lt;class Alloc&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a);
    template &lt;class Alloc&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const Types&amp;...);
    template &lt;class Alloc, class... UTypes&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, UTypes&amp;&amp;...);
    template &lt;class Alloc&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const tuple&amp;);
    template &lt;class Alloc&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, tuple&amp;&amp;);
    template &lt;class Alloc, class... UTypes&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const tuple&lt;UTypes...&gt;&amp;);
    template &lt;class Alloc, class... UTypes&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, tuple&lt;UTypes...&gt;&amp;&amp;);
    template &lt;class Alloc, class U1, class U2&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const pair&lt;U1, U2&gt;&amp;);
    template &lt;class Alloc, class U1, class U2&gt;
      <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, pair&lt;U1, U2&gt;&amp;&amp;);

    [..]
  };
}
</pre></blockquote>
</li>
<li><p>Change 20.4.2.1 [tuple.cnstr] around p6 as indicated:</p>
<blockquote><pre>
<ins><i>EXPLICIT</i></ins><del>explicit</del> constexpr tuple(const Types&amp;...);
</pre><blockquote><p>
<del>-6- <em>Requires</em>: <tt>is_copy_constructible&lt;Ti&gt;::value</tt> is true for all <em>i</em>.</del>
<p/>
-7- <em>Effects</em>: <ins>The constructors initialize</ins><del>Initializes</del> each element with the value of the corresponding parameter.
<p/>
<ins>-?- <em>Remarks</em>: The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>sizeof...(Types) &gt;= 1</tt>,</ins></p></li>
	<li><p><ins><tt>is_copy_constructible&lt;Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const Ti&amp;, Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>sizeof...(Types) &gt;= 1</tt>,</ins></p></li>
	<li><p><ins><tt>is_copy_constructible&lt;Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const Ti&amp;, Ti&gt;::value</tt> is <tt>false</tt> for at least one <em>i</em></ins></p></li>
	</ul>
</blockquote></blockquote>
<p>
</li>
<li><p>Change 20.4.2.1 [tuple.cnstr] around p8 as indicated:</p>
<blockquote><pre>
template &lt;class... UTypes&gt;
  <ins><i>EXPLICIT</i></ins><del>explicit</del> constexpr tuple(UTypes&amp;&amp;... u);
</pre><blockquote><p>
-8- <em>Requires</em>: <tt>sizeof...(Types) == sizeof...(UTypes)</tt>. <del><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> 
is true for all <em>i</em>.</del>
<p/>
-9- <em>Effects</em>: <ins>The constructors initialize</ins><del>Initializes</del> the elements in the tuple with the corresponding value in <tt>std::forward&lt;UTypes&gt;(u)</tt>.
<p/>
-10- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless each type in <tt>UTypes</tt> is implicitly convertible 
	to its corresponding type in <tt>Types</tt>.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>sizeof...(Types) &gt;= 1</tt>,</ins></p></li>
	<li><p><ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;Ui&amp;&amp;, Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>sizeof...(Types) &gt;= 1</tt>,</ins></p></li>
	<li><p><ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;Ui&amp;&amp;, Ti&gt;::value</tt> is <tt>false</tt> for at least one <em>i</em></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>
<li><p>Change 20.4.2.1 [tuple.cnstr] around p15 as indicated:</p>
<blockquote><pre>
template &lt;class... UTypes&gt; <ins><i>EXPLICIT</i></ins> constexpr tuple(const tuple&lt;UTypes...&gt;&amp; u);
</pre><blockquote><p>
-15- <em>Requires</em>: <tt>sizeof...(Types) == sizeof...(UTypes)</tt>. <del><tt>is_constructible&lt;Ti, const Ui&amp;&gt;::value</tt> 
	 is true for all <em>i</em>.</del>
<p/>
-16- <em>Effects</em>: <ins>The constructors initialize</ins><del>Constructs</del> each element of <tt>*this</tt> with the corresponding element of <tt>u</tt>.
<p/>
-17- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless 
	<tt>const Ui&amp;</tt> is implicitly convertible to <tt>Ti</tt> for all <em>i</em>.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, const Ui&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const Ui&amp;, Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, const Ui&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const Ui&amp;, Ti&gt;::value</tt> is <tt>false</tt> for at least one <em>i</em></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>
<li><p>Change 20.4.2.1 [tuple.cnstr] around p18 as indicated:</p>
<blockquote><pre>
template &lt;class... UTypes&gt; <ins><i>EXPLICIT</i></ins> constexpr tuple(tuple&lt;UTypes...&gt;&amp;&amp; u);
</pre><blockquote><p>
-18- <em>Requires</em>: <tt>sizeof...(Types) == sizeof...(UTypes)</tt>. <del><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> 
is true for all <em>i</em>.</del>
<p/>
-19- <em>Effects</em>: For all <em>i</em>, <ins>the constructors</ins> initialize<del>s</del> the <em>i</em><sup>th</sup> element of 
<tt>*this</tt> with <tt>std::forward&lt;Ui&gt;(get&lt;<em>i</em>&gt;(u))</tt>.
<p/>
-20- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless each type in <tt>UTypes</tt> 
is implicitly convertible to its corresponding type in <tt>Types</tt>.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;Ui&amp;&amp;, Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;Ui&amp;&amp;, Ti&gt;::value</tt> is <tt>false</tt> for at least one <em>i</em></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>
<li>
<p>Change 20.4.2.1 [tuple.cnstr] around p21 as indicated:</p>
<blockquote><pre>
template &lt;class U1, class U2&gt; <ins><i>EXPLICIT</i></ins> constexpr tuple(const pair&lt;U1, U2&gt;&amp; u);
</pre><blockquote><p>
-21- <em>Requires</em>:  <tt>sizeof...(Types) == 2</tt>. <del><tt>is_constructible&lt;T0, const U1&amp;&gt;::value</tt> is true for 
the first type <tt>T0</tt> in <tt>Types</tt> and <tt>is_constructible&lt;T1, const U2&amp;&gt;::value</tt> is true for the second 
type <tt>T1</tt> in <tt>Types</tt>.</del>
<p/>
-22- <em>Effects</em>: <ins>The constructors initialize</ins><del>Constructs</del> the first element with <tt>u.first</tt> and the second element with <tt>u.second</tt>.
<p/>
-23- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless <tt>const U1&amp;</tt> 
is implicitly convertible to <tt>T0</tt> and <tt>const U2&amp;</tt> is implicitly convertible to <tt>T1</tt>.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, const Ui&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const Ui&amp;, Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, const Ui&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;const Ui&amp;, Ti&gt;::value</tt> is <tt>false</tt> for at least one <em>i</em></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>
<li><p>Change 20.4.2.1 [tuple.cnstr] around p24 as indicated:</p>
<blockquote><pre>
template &lt;class U1, class U2&gt; <ins><i>EXPLICIT</i></ins> constexpr tuple(pair&lt;U1, U2&gt;&amp;&amp; u);
</pre><blockquote><p>
-24- <em>Requires</em>: <tt>sizeof...(Types) == 2</tt>. <del><tt>is_constructible&lt;T0, U1&amp;&amp;&gt;::value</tt> is true for 
the first type <tt>T0</tt> in <tt>Types</tt> and <tt>is_constructible&lt;T1, U2&amp;&amp;&gt;::value</tt> is true for the 
second type <tt>T1</tt> in <tt>Types</tt>.</del>
<p/>
-25- <em>Effects</em>: <ins>The constructors i</ins><del>I</del>nitialize<del>s</del> the first element with 
<tt>std::forward&lt;U1&gt;(u.first)</tt> and the second element with <tt>std::forward&lt;U2&gt;(u.second)</tt>.
<p/>
-26- <em>Remark<ins>s</ins></em>: <del>This constructor shall not participate in overload resolution unless <tt>U1</tt> is implicitly 
convertible to <tt>T0</tt> and <tt>U2</tt> is implicitly convertible to <tt>T1</tt>.</del>
	<ins>The non-explicit constructor shall not participate in overload resolution unless</ins>
</p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;Ui&amp;&amp;, Ti&gt;::value</tt> is <tt>true</tt> for all <em>i</em></ins></p></li>
	</ul>
	<p><ins>The explicit constructor shall not participate in overload resolution unless</ins></p>
	<ul>
	<li><p><ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value</tt> is <tt>true</tt> for all <em>i</em>, and</ins></p></li>
	<li><p><ins><tt>is_convertible&lt;Ui&amp;&amp;, Ti&gt;::value</tt> is <tt>false</tt> for at least one <em>i</em></ins></p></li>
	</ul>
</blockquote></blockquote>
</li>

<li><p>Change 20.4.2.1 [tuple.cnstr] around p27 as indicated:</p>
<blockquote><pre>
template &lt;class Alloc&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a);
template &lt;class Alloc&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const Types&amp;...);
template &lt;class Alloc, class... UTypes&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, UTypes&amp;&amp;...);
template &lt;class Alloc&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const tuple&amp;);
template &lt;class Alloc&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, tuple&amp;&amp;);
template &lt;class Alloc, class... UTypes&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const tuple&lt;UTypes...&gt;&amp;);
template &lt;class Alloc, class... UTypes&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, tuple&lt;UTypes...&gt;&amp;&amp;);
template &lt;class Alloc, class U1, class U2&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, const pair&lt;U1, U2&gt;&amp;);
template &lt;class Alloc, class U1, class U2&gt;
  <ins><i>EXPLICIT</i></ins> tuple(allocator_arg_t, const Alloc&amp; a, pair&lt;U1, U2&gt;&amp;&amp;);
</pre><blockquote><p>
-27- <em>Requires</em>: <tt>Alloc</tt> shall meet the requirements for an <tt>Allocator</tt> (17.6.3.5).
<p/>
-28- <em>Effects</em>: Equivalent to the preceding constructors except that each element is constructed with uses-allocator
construction (20.8.7.2).
</p>
</blockquote></blockquote>
</li>

</ol>
<p>
</p>

<h2><a name="ImplHint"></a>Implementation Hint</h2>

<p>
The following example presents how to constrain even non-template functions such as the constructors
that directly take the element types.
</p>

<blockquote><pre>
template&lt;class T1, class T2>
struct pair {

  [&hellip;]

  template&lt;class U1 = T1, class U2 = T2,
    typename enable_if&lt;
      is_copy_constructible&lt;U1>::value &amp;&amp; is_copy_constructible&lt;U2>::value &amp;&amp;
      is_convertible&lt;const U1&amp;, U1>::value &amp;&amp; is_convertible&lt;const U2&amp;, U2>::value
    , bool>::type = false
  >
  constexpr pair(const T1&amp;, const T2&amp;);

  template&lt;class U1 = T1, class U2 = T2,
    typename enable_if&lt;
      is_copy_constructible&lt;U1>::value &amp;&amp; is_copy_constructible&lt;U2>::value &amp;&amp;
      !(is_convertible&lt;const U1&amp;, U1>::value &amp;&amp; is_convertible&lt;const U2&amp;, U2>::value)
    , bool>::type = false
  >
  explicit constexpr pair(const T1&amp;, const T2&amp;);
};
</pre></blockquote>

<h2><a name="Akn"></a>Acknowledgements</h2>
<p>
I would like to thank Howard Hinnant for his very helpful discussions and comments during reviews of this paper and for
his motivating example. Thanks also to Jonathan Wakely for his review that improved this proposal to a large extend.
Thanks as well go to Mike Spertus for helping to improve the rationale.
</p>
</body></html>