Topic: std::swap breaking change


Author: Casey Carter <cartec69@gmail.com>
Date: Tue, 5 Apr 2016 19:24:35 -0700 (PDT)
Raw View
------=_Part_1697_1015115143.1459909475119
Content-Type: multipart/alternative;
 boundary="----=_Part_1698_1753595987.1459909475119"

------=_Part_1698_1753595987.1459909475119
Content-Type: text/plain; charset=UTF-8

Soliciting input from the list before I submit this issue to the LWG chair:

[utility.swap]/1 states:

*Remarks*: This function shall not participate in overload resolution unless is_move_constructible<T>::value
is true and is_move_assignable<T>::value is true. ...

The addition of constraints is a breaking change relative to C++14.
Explicit specializations of std::swap for non-movable types were previously
valid:

struct immobile {
    immobile() = default;
    immobile(immobile&&) = delete;
    immobile& operator=(immobile&&) = delete;
};

class cxx98_uncopyable {
    cxx98_uncopyable(const cxx98_uncopyable&);
    cxx98_uncopyable& operator=(const cxx98_uncopyable&);
public:
    cxx98_uncopyable() {}
};

namespace std {
    template<> void swap<immobile&>(immobile&, immobile&) noexcept(true) {}
    template<> void swap<cxx98_uncopyable&>(cxx98_uncopyable&,
cxx98_uncopyable&) {}
}


With the std::swap template constrained as in the WP, no such
specializations can be generated from the base template, so these explicit
specializations are ill-formed.

Similarly, [utility.swap]/4 constrains the array overload of std::swap:

*Remarks*: This function shall not participate in overload resolution
unless is_swappable_v<T> is true.

C++14 programs could (in theory) explicitly specialize std::swap for arrays
of some type T that fails the WP's is_swappable test. This is also a
breaking change, albeit one unlikely to manifest in real code.

Proposed Resolution:
Insert a new section in Appendix C before the existing section C.4.5:

<ins>C.4.x Clause 20: swap function templates [diff.cpp14.swap]</ins>
<ins>\ref{utility.swap}</ins>

<ins>Change: Addition of constraints to the swap function templates.</ins>
<ins>Rationale: To enable the addition of traits is_swappable,
is_nothrow_swappable, is_swappable_with, and
is_nothrow_swappable_with.</ins>

<ins>Effect on Original Feature: Valid C++14 code that explicitly
specializes std::swap for types that are not move constructible or not move
assignable is ill-formed in this International Standard.</ins>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d5963167-4566-413d-a134-0368b09cadbe%40isocpp.org.

------=_Part_1698_1753595987.1459909475119
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div style=3D"font-family: arial, sans-serif; font-size: s=
mall;">Soliciting input from the list before I submit this issue to the LWG=
 chair:</div><div style=3D"font-family: arial, sans-serif; font-size: small=
;"><br></div><div style=3D"font-family: arial, sans-serif; font-size: small=
;">[utility.swap]/1 states:</div><blockquote style=3D"font-family: arial, s=
ans-serif; font-size: small; border: none; padding: 0px;"><pre><font color=
=3D"#000000"><i>Remarks</i>: This function shall not participate in overloa=
d resolution unless is_move_constructible&lt;T&gt;::<wbr>value
is true and is_move_assignable&lt;T&gt;::value is true. ...<br></font></pre=
></blockquote><span style=3D"font-family: arial, sans-serif; font-size: sma=
ll;">The addition of constraints is a breaking change relative to C++14. Ex=
plicit specializations of std::swap for non-movable types were previously v=
alid:</span><br style=3D"font-family: arial, sans-serif; font-size: small;"=
><div style=3D"font-family: arial, sans-serif; font-size: small;"><br></div=
><blockquote style=3D"font-family: arial, sans-serif; font-size: small; bor=
der: none; padding: 0px;"><div><font face=3D"monospace, monospace">struct i=
mmobile {</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 immobile() =3D default;</font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 immobile(immobile&amp;&amp;) =3D delete;</font></div><d=
iv><font face=3D"monospace, monospace">=C2=A0 =C2=A0 immobile&amp; operator=
=3D(immobile&amp;&amp;) =3D delete;</font></div><div><font face=3D"monospac=
e, monospace">};</font></div><div><font face=3D"monospace, monospace"><br><=
/font></div><div><font face=3D"monospace, monospace">class cxx98_uncopyable=
 {</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 cxx98=
_uncopyable(const cxx98_uncopyable&amp;);</font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 cxx98_uncopyable&amp; operator=3D(const c=
xx98_uncopyable&amp;);</font></div><div><font face=3D"monospace, monospace"=
>public:</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0=
 cxx98_uncopyable() {}</font></div><div><font face=3D"monospace, monospace"=
>};</font></div><div><font face=3D"monospace, monospace"><br></font></div><=
div><font face=3D"monospace, monospace">namespace std {</font></div><div><f=
ont face=3D"monospace, monospace">=C2=A0 =C2=A0 template&lt;&gt; void swap&=
lt;immobile&amp;&gt;(immobile&amp;, immobile&amp;) noexcept(true) {}</font>=
</div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 template&lt;&g=
t; void swap&lt;cxx98_uncopyable&amp;&gt;(cxx98_<wbr>uncopyable&amp;, cxx98=
_uncopyable&amp;) {}</font></div><div><font face=3D"monospace, monospace">}=
</font></div></blockquote><div style=3D"font-family: arial, sans-serif; fon=
t-size: small;"><br></div><div style=3D"font-family: arial, sans-serif; fon=
t-size: small;">With the std::swap template constrained as in the WP, no su=
ch specializations can be generated from the base template, so these explic=
it specializations are ill-formed.</div><div style=3D"font-family: arial, s=
ans-serif; font-size: small;"><br></div><div style=3D"font-family: arial, s=
ans-serif; font-size: small;">Similarly, [utility.swap]/4 constrains the ar=
ray overload of std::swap:</div><blockquote style=3D"font-family: arial, sa=
ns-serif; font-size: small; border: none; padding: 0px;"><font face=3D"mono=
space, monospace"><i>Remarks</i>: This function shall not participate in ov=
erload resolution unless is_swappable_v&lt;T&gt; is true.</font></blockquot=
e><div style=3D"font-family: arial, sans-serif; font-size: small;">C++14 pr=
ograms could (in theory) explicitly specialize std::swap for arrays of some=
 type T that fails the WP&#39;s=C2=A0<font face=3D"monospace, monospace">is=
_swappable</font>=C2=A0test. This is also a breaking change, albeit one unl=
ikely to manifest in real code.<br></div><div style=3D"font-family: arial, =
sans-serif; font-size: small;"><br></div><div style=3D"font-family: arial, =
sans-serif; font-size: small;">Proposed Resolution:</div><div style=3D"font=
-family: arial, sans-serif; font-size: small;">Insert a new section in Appe=
ndix C before the existing section=C2=A0C.4.5:</div><div style=3D"font-fami=
ly: arial, sans-serif; font-size: small;"><br></div><div style=3D"font-fami=
ly: arial, sans-serif; font-size: small;"><blockquote style=3D"margin: 0px =
0px 0px 40px; border: none; padding: 0px;"><div>&lt;ins&gt;C.4.x Clause 20:=
 swap function templates [diff.cpp14.swap]&lt;/ins&gt;</div><div>&lt;ins&gt=
;\ref{utility.swap}&lt;/ins&gt;<br></div></blockquote><blockquote style=3D"=
margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div>&lt;ins&gt;Chan=
ge: Addition of constraints to the swap function templates.&lt;/ins&gt;</di=
v><div>&lt;ins&gt;Rationale: To enable the addition of traits is_swappable,=
 is_nothrow_swappable, is_swappable_with, and is_nothrow_swappable_with.&lt=
;/ins&gt;<br></div></blockquote><blockquote style=3D"margin: 0px 0px 0px 40=
px; border: none; padding: 0px;">&lt;ins&gt;Effect on Original Feature: Val=
id C++14 code that explicitly specializes std::swap for types that are not =
move constructible or not move assignable is ill-formed in this Internation=
al Standard.&lt;/ins&gt;</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d5963167-4566-413d-a134-0368b09cadbe%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d5963167-4566-413d-a134-0368b09cadbe=
%40isocpp.org</a>.<br />

------=_Part_1698_1753595987.1459909475119--
------=_Part_1697_1015115143.1459909475119--

.


Author: =?UTF-8?Q?Daniel_Kr=C3=BCgler?= <daniel.kruegler@gmail.com>
Date: Wed, 6 Apr 2016 07:29:02 +0200
Raw View
"2016-04-06 4:24 GMT+02:00 Casey Carter <cartec69@gmail.com>:
> Soliciting input from the list before I submit this issue to the LWG chair:
>
> [utility.swap]/1 states:
>
> Remarks: This function shall not participate in overload resolution unless
> is_move_constructible<T>::value
> is true and is_move_assignable<T>::value is true. ...
>
> The addition of constraints is a breaking change relative to C++14. Explicit
> specializations of std::swap for non-movable types were previously valid:
>
> struct immobile {
>     immobile() = default;
>     immobile(immobile&&) = delete;
>     immobile& operator=(immobile&&) = delete;
> };
>
> class cxx98_uncopyable {
>     cxx98_uncopyable(const cxx98_uncopyable&);
>     cxx98_uncopyable& operator=(const cxx98_uncopyable&);
> public:
>     cxx98_uncopyable() {}
> };
>
> namespace std {
>     template<> void swap<immobile&>(immobile&, immobile&) noexcept(true) {}
>     template<> void swap<cxx98_uncopyable&>(cxx98_uncopyable&,
> cxx98_uncopyable&) {}
> }
>
>
> With the std::swap template constrained as in the WP, no such
> specializations can be generated from the base template, so these explicit
> specializations are ill-formed.

This is correct and that had been foreseen by the design rationale of

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4426.html

The most relevant part starts with the sentence

"When considering to constrain the two swap templates from header
<utility> it should be highlighted that doing this could potentially
break existing code."

The following argumentation points already out that your constructed
example was not supported by previous C++ standards because of the
already present requirement:

"Requires: Type T shall be MoveConstructible (Table 20) and
MoveAssignable (Table 22).

And in the Library introductory Clause 17 we have in [namespace.std]:

"A program may add a template specialization for any standard library
template to namespace std only if the declaration depends on a
user-defined type and the specialization meets the standard library
requirements for the original template and is not explicitly
prohibited."

This doesn't hold for immobile nor for cxx98_uncopyable. Those types
should never had *specialized* std::swap, but they could (and they
still can) provide a free swap function accessible via ADL.

> Similarly, [utility.swap]/4 constrains the array overload of std::swap:
>
> Remarks: This function shall not participate in overload resolution unless
> is_swappable_v<T> is true.
>
> C++14 programs could (in theory) explicitly specialize std::swap for arrays
> of some type T that fails the WP's is_swappable test. This is also a
> breaking change, albeit one unlikely to manifest in real code.
>
> Proposed Resolution:
> Insert a new section in Appendix C before the existing section C.4.5:
>
> <ins>C.4.x Clause 20: swap function templates [diff.cpp14.swap]</ins>
> <ins>\ref{utility.swap}</ins>
>
> <ins>Change: Addition of constraints to the swap function templates.</ins>
> <ins>Rationale: To enable the addition of traits is_swappable,
> is_nothrow_swappable, is_swappable_with, and
> is_nothrow_swappable_with.</ins>
>
> <ins>Effect on Original Feature: Valid C++14 code that explicitly
> specializes std::swap for types that are not move constructible or not move
> assignable is ill-formed in this International Standard.</ins>

Technically I don't think that we should add this to the appendix,
because the breakage does not exist by the previous requirements.

- Daniel

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGNvRgADsWCLwt3Gx2bSmD6usddUssHv4mjHCPLF7xq8EmxBUg%40mail.gmail.com.

.


Author: Casey Carter <cartec69@gmail.com>
Date: Wed, 6 Apr 2016 14:01:55 -0700 (PDT)
Raw View
------=_Part_3002_1543123148.1459976516049
Content-Type: multipart/alternative;
 boundary="----=_Part_3003_1115899219.1459976516049"

------=_Part_3003_1115899219.1459976516049
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, April 5, 2016 at 10:29:04 PM UTC-7, Daniel Kr=C3=BCgler wrote:
>
> "2016-04-06 4:24 GMT+02:00 Casey Carter <cart...@gmail.com <javascript:>>=
:=20
>
> > With the std::swap template constrained as in the WP, no such=20
> > specializations can be generated from the base template, so these=20
> explicit=20
> > specializations are ill-formed.=20
>
> This is correct and that had been foreseen by the design rationale of=20
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4426.html=20
>
> The most relevant part starts with the sentence=20
>
> "When considering to constrain the two swap templates from header=20
> <utility> it should be highlighted that doing this could potentially=20
> break existing code."=20
>
> The following argumentation points already out that your constructed=20
> example was not supported by previous C++ standards because of the=20
> already present requirement:=20
>
> "Requires: Type T shall be MoveConstructible (Table 20) and=20
> MoveAssignable (Table 22).=20
>
> And in the Library introductory Clause 17 we have in [namespace.std]:=20
>
> "A program may add a template specialization for any standard library=20
> template to namespace std only if the declaration depends on a=20
> user-defined type and the specialization meets the standard library=20
> requirements for the original template and is not explicitly=20
> prohibited."=20
>

I've always interpreted "meets the standard library requirements for the=20
original template" to mean that user-defined specializations must satisfy=
=20
the requirements imposed by the specification on the specializations of the=
=20
base template (e.g., std::allocator<my_type> must meet the allocator=20
requirements), not to to mean that specializations must enforce the same=20
requirements on their parameters as the base template. Intuitively,=20
weakening of preconditions or strengthening of postconditions should not=20
interfere with equational reasoning.
=20

>
> This doesn't hold for immobile nor for cxx98_uncopyable. Those types=20
> should never had *specialized* std::swap, but they could (and they=20
> still can) provide a free swap function accessible via ADL.=20
>

It's hard to find much justification for specializing *any* function=20
template, let alone std::swap. It has never so much as crossed my mind to=
=20
suggest that these specializations should not be broken; I only want to be=
=20
sure we are giving full disclosure to our users.
=20

> > Proposed Resolution:=20
> > Insert a new section in Appendix C before the existing section C.4.5:=
=20
> >=20
> > <ins>C.4.x Clause 20: swap function templates [diff.cpp14.swap]</ins>=
=20
> > <ins>\ref{utility.swap}</ins>=20
> >=20
> > <ins>Change: Addition of constraints to the swap function=20
> templates.</ins>=20
> > <ins>Rationale: To enable the addition of traits is_swappable,=20
> > is_nothrow_swappable, is_swappable_with, and=20
> > is_nothrow_swappable_with.</ins>=20
> >=20
> > <ins>Effect on Original Feature: Valid C++14 code that explicitly=20
> > specializes std::swap for types that are not move constructible or not=
=20
> move=20
> > assignable is ill-formed in this International Standard.</ins>=20
>
> Technically I don't think that we should add this to the appendix,=20
> because the breakage does not exist by the previous requirements.=20
>
> - Daniel=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/8979ef6f-7f32-4bc7-b90f-8550e6bfe4b3%40isocpp.or=
g.

------=_Part_3003_1115899219.1459976516049
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, April 5, 2016 at 10:29:04 PM UTC-7, Daniel Kr=
=C3=BCgler wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&quot;2016-04=
-06 4:24 GMT+02:00 Casey Carter &lt;<a href=3D"javascript:" target=3D"_blan=
k" gdf-obfuscated-mailto=3D"EeJOY97bAQAJ" rel=3D"nofollow" onmousedown=3D"t=
his.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;=
javascript:&#39;;return true;">cart...@gmail.com</a>&gt;:
<br>&gt; With the std::swap template constrained as in the WP, no such
<br>&gt; specializations can be generated from the base template, so these =
explicit
<br>&gt; specializations are ill-formed.
<br>
<br>This is correct and that had been foreseen by the design rationale of
<br>
<br><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n442=
6.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;=
http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2=
Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4426.html\46sa\75D\46sntz\0751\46usg\75AFQj=
CNEfSHy4-2TLAzubXOTLKtATWqWaVw&#39;;return true;" onclick=3D"this.href=3D&#=
39;http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc2=
2%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fn4426.html\46sa\75D\46sntz\0751\46usg\75A=
FQjCNEfSHy4-2TLAzubXOTLKtATWqWaVw&#39;;return true;">http://www.open-std.or=
g/jtc1/<wbr>sc22/wg21/docs/papers/2015/<wbr>n4426.html</a>
<br>
<br>The most relevant part starts with the sentence
<br>
<br>&quot;When considering to constrain the two swap templates from header
<br>&lt;utility&gt; it should be highlighted that doing this could potentia=
lly
<br>break existing code.&quot;
<br>
<br>The following argumentation points already out that your constructed
<br>example was not supported by previous C++ standards because of the
<br>already present requirement:
<br>
<br>&quot;Requires: Type T shall be MoveConstructible (Table 20) and
<br>MoveAssignable (Table 22).
<br>
<br>And in the Library introductory Clause 17 we have in [namespace.std]:
<br>
<br>&quot;A program may add a template specialization for any standard libr=
ary
<br>template to namespace std only if the declaration depends on a
<br>user-defined type and the specialization meets the standard library
<br>requirements for the original template and is not explicitly
<br>prohibited.&quot;
<br></blockquote><div><br></div><div>I&#39;ve always interpreted &quot;meet=
s the standard library requirements for the original template&quot; to mean=
 that user-defined specializations must satisfy the requirements imposed by=
 the specification on the specializations of the base template (e.g., std::=
allocator&lt;my_type&gt; must meet the allocator requirements), not to to m=
ean that specializations must enforce the same requirements on their parame=
ters as the base template. Intuitively, weakening of preconditions or stren=
gthening of postconditions should not interfere with equational reasoning.<=
/div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>This doesn&#39;t hold for immobile nor for cxx98_uncopyable. Those type=
s
<br>should never had *specialized* std::swap, but they could (and they
<br>still can) provide a free swap function accessible via ADL.
<br></blockquote><div><br></div><div>It&#39;s hard to find much justificati=
on for specializing *any* function template, let alone std::swap. It has ne=
ver so much as crossed my mind to suggest that these specializations should=
 not be broken; I only want to be sure we are giving full disclosure to our=
 users.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
&gt; Proposed Resolution:
<br>&gt; Insert a new section in Appendix C before the existing section C.4=
..5:
<br>&gt;
<br>&gt; &lt;ins&gt;C.4.x Clause 20: swap function templates [diff.cpp14.sw=
ap]&lt;/ins&gt;
<br>&gt; &lt;ins&gt;\ref{utility.swap}&lt;/ins&gt;
<br>&gt;
<br>&gt; &lt;ins&gt;Change: Addition of constraints to the swap function te=
mplates.&lt;/ins&gt;
<br>&gt; &lt;ins&gt;Rationale: To enable the addition of traits is_swappabl=
e,
<br>&gt; is_nothrow_swappable, is_swappable_with, and
<br>&gt; is_nothrow_swappable_with.&lt;/<wbr>ins&gt;
<br>&gt;
<br>&gt; &lt;ins&gt;Effect on Original Feature: Valid C++14 code that expli=
citly
<br>&gt; specializes std::swap for types that are not move constructible or=
 not move
<br>&gt; assignable is ill-formed in this International Standard.&lt;/ins&g=
t;
<br>
<br>Technically I don&#39;t think that we should add this to the appendix,
<br>because the breakage does not exist by the previous requirements.
<br>
<br>- Daniel
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8979ef6f-7f32-4bc7-b90f-8550e6bfe4b3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8979ef6f-7f32-4bc7-b90f-8550e6bfe4b3=
%40isocpp.org</a>.<br />

------=_Part_3003_1115899219.1459976516049--
------=_Part_3002_1543123148.1459976516049--

.


Author: =?UTF-8?Q?Daniel_Kr=C3=BCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 7 Apr 2016 00:08:05 +0200
Raw View
2016-04-06 23:01 GMT+02:00 Casey Carter <cartec69@gmail.com>:
> On Tuesday, April 5, 2016 at 10:29:04 PM UTC-7, Daniel Kr=C3=BCgler wrote=
:
>>
>> "2016-04-06 4:24 GMT+02:00 Casey Carter <cart...@gmail.com>:
>> > With the std::swap template constrained as in the WP, no such
>> > specializations can be generated from the base template, so these
>> > explicit
>> > specializations are ill-formed.
>>
>> This is correct and that had been foreseen by the design rationale of
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4426.html
>>
>> The most relevant part starts with the sentence
>>
>> "When considering to constrain the two swap templates from header
>> <utility> it should be highlighted that doing this could potentially
>> break existing code."
>>
>> The following argumentation points already out that your constructed
>> example was not supported by previous C++ standards because of the
>> already present requirement:
>>
>> "Requires: Type T shall be MoveConstructible (Table 20) and
>> MoveAssignable (Table 22).
>>
>> And in the Library introductory Clause 17 we have in [namespace.std]:
>>
>> "A program may add a template specialization for any standard library
>> template to namespace std only if the declaration depends on a
>> user-defined type and the specialization meets the standard library
>> requirements for the original template and is not explicitly
>> prohibited."
>
> I've always interpreted "meets the standard library requirements for the
> original template" to mean that user-defined specializations must satisfy
> the requirements imposed by the specification on the specializations of t=
he
> base template (e.g., std::allocator<my_type> must meet the allocator
> requirements), not to to mean that specializations must enforce the same
> requirements on their parameters as the base template. Intuitively,
> weakening of preconditions or strengthening of postconditions should not
> interfere with equational reasoning.

I tentatively disagree with your interpretation based on our
experience with "concepts 0", albeit the standard wording might not be
strict enough to discriminate these two points of view. Concepts 0
didn't made it into C++11 but a lot of experience has been won at that
time and I think the current (non-concept-based) rules of functions
specializations and Concepts Lite agree with my interpretation. If I
defined a primary constrained template such as

template<Copyable T>
class Copier {};

it was not possible to define specializations of Copier where Copyable
T is *not* imposed. Specializations may impose stronger constraints
but not weaker ones.

Example (Using now gcc 6 with -fconcepts which implements the current
Concepts Lite technical specification):

#include <type_traits>

template<typename T> concept bool Copyable =3D
std::is_copy_constructible<T>::value;

template<Copyable T>
struct Copier {};

struct NonCopyable
{
  NonCopyable(const NonCopyable&) =3D delete;
};

template<>
struct Copier<NonCopyable> {};

Diagnostics:

 error: template constraint failure
 struct Copier<NonCopyable> {};
                          ^
note:   constraints not satisfied
note:   concept 'Copyable<NonCopyable>' was not satisfied

So I think that we have a similar reasoning here and the ideas of the
logical imposition of constraints onto template parameters has existed
before C++11 has been published (albeit it was not possible to enforce
that by code).

>> This doesn't hold for immobile nor for cxx98_uncopyable. Those types
>> should never had *specialized* std::swap, but they could (and they
>> still can) provide a free swap function accessible via ADL.
>
> It's hard to find much justification for specializing *any* function
> template, let alone std::swap. It has never so much as crossed my mind to
> suggest that these specializations should not be broken; I only want to b=
e
> sure we are giving full disclosure to our users.

Well, you are always free to submit an LWG issue, especially if the
existing interpretations of the extend of the Clause 17 requirements
do differ. Personally I wouldn't be too concerned to make such an
appendix C addition.

If we consider this issue, I would really like to have a much more
obvious breakage of C++11 (versus C++98/03) added to the appendix: The
addition of an exception specification to std::swap had caused several
existing swap specialization to break, because their effective
exception specification didn't match the one that resulted from the
implicit exception specifications from move/copy assignment operator
and move/copy constructor. This second case is IMO a much more real
breakage compared to adding compile-time constraints onto std::swap,
because the compile-time constraints did already exist before by the
imposed library constraints but the exception-specification
constraints did not exist before.

Thanks,

- Daniel

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CAGNvRgCHBVrvfpikDDTO5svEugpe%2BVsdNO%2BJG6ZD%2B=
u1AcdE6Qg%40mail.gmail.com.

.