Topic: Making std::vector<std::unique_ptr<void>> not be


Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Fri, 23 Aug 2013 16:39:14 +0200
Raw View
Oh, right, I almost forgot to ask if maybe concepts would help here as well=
?
Mit freundlichen Gr=FC=DFen,

Martinho


On Fri, Aug 23, 2013 at 4:08 PM, Martinho Fernandes
<martinho.fernandes@gmail.com> wrote:
> First of all, let's make sure we are all aware of the fact that an
> expression that would normally be ill-formed may still count as
> "well-formed" for some purposes:
> http://stackoverflow.com/q/14815998/46642
>
> Now, as far as I can see, the standard makes
> std::vector<std::unique_ptr<void>> have a copy constructor, even
> though it makes any program that instantiates it ill-formed as a
> consequence of its defined semantics. Please correct me if my reading
> of the standard here is wrong and makes all of this moot.
>
> These two facts explain why this program is well-formed:
>
> http://coliru.stacked-crooked.com/view?id=3D735d0e4868baddb9fa210cbf18ca0=
2e7-f0bd80647c520ac4f6fb0347af37c64b
>
> And this is merely the best example I came up with. There are other
> similar issues the standard library, and there is also the general
> case of traits testing arbitrary functions in other libraries (which I
> first explored here
> http://flamingdangerzone.com/cxx11/2013/02/11/to-sfinae-or-not-to-sfinae)
>
> This is quite unfortunate, I'd say. As a library designer the
> inability to work around this is something that has been annoying me
> for a while.
>
> I have been wondering about two possible changes to ease this
> nuissance. The first one would be to fix the standard library so that
> the constructor is only there for actually copy constructible Ts (and
> similar fixes to other functions). I don't know how much code this
> would break, and more importantly, how much non-iffy code this would
> break.
>
> The second one would involve giving library designers the ability to
> look past the "immediate context", something like `wellformed(expr)`
> operator. I also don't know how feasible that would be and it would
> certainly make this part of the language even more complex.
>
> I know the deadline for submissions is soon, and I don't think I would
> have the time to think everything through to make a decent proposal.
> But I want to know if others think this is a problem that needs
> solving like I do, and if the solutions are worth making into a future
> proposal, potentially for C++17.
>
> Mit freundlichen Gr=FC=DFen,
>
> Martinho

--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Fri, 23 Aug 2013 17:55:16 -0700 (PDT)
Raw View
------=_Part_366_30059536.1377305716697
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

(Google's editor seems to eat my previous answer, if it didn't and was just=
=20
delayed, then sorry for the double post)

2013. augusztus 23., p=C3=A9ntek 16:08:51 UTC+2 id=C5=91pontban R. Martinho=
 Fernandes=20
a k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> First of all, let's make sure we are all aware of the fact that an=20
> expression that would normally be ill-formed may still count as=20
> "well-formed" for some purposes:=20
> http://stackoverflow.com/q/14815998/46642=20
>
As one of the comments pointed out, std::is_constructible checks if there=
=20
is a constructor, not if there is a well-formed constructor. The=20
constructor in question is still ill-formed everywhere.


> Now, as far as I can see, the standard makes=20
> std::vector<std::unique_ptr<void>> have a copy constructor, even=20
> though it makes any program that instantiates it ill-formed as a=20
> consequence of its defined semantics. Please correct me if my reading=20
> of the standard here is wrong and makes all of this moot.=20
>

I think that's not true, although I agree it is not obvious.

Check 23.2.1 [container.requirements.general], table 96, there is a row for=
=20
expressions with STL container copy constructors:
X(a) Requires:T is CopyInsertable into X (see below). post: a =3D=3D X(a).
CopyInsertable is:
in addition to T being MoveInsertable into X, the following expression is=
=20
well-formed: allocator_traits<A>::construct(m, p, v) and its evaluation=20
causes the following postcondition to hold: The value of v is unchanged and=
=20
is equivalent to *p.
For the default allocator (what calls placement new in construct), it is=20
obvious that this is not true with unique_ptr. It's not that obvious, but=
=20
you cannot write a custom allocator what can construct a unique_ptr with=20
the postcondition being valid too.

Thus, the postcondition for X(a) is void, thus it is ill-formed in case of=
=20
vector<unique_ptr<int>>, and for all containers with unique_ptr.

Regards, Robert

--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr">(Google's editor seems to eat my previous answer, if it di=
dn't and was just delayed, then sorry for the double post)<br><br>2013. aug=
usztus 23., p=C3=A9ntek 16:08:51 UTC+2 id=C5=91pontban R. Martinho Fernande=
s a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">First of all, let's make sure we are all aware of the fact that an
<br>expression that would normally be ill-formed may still count as
<br>"well-formed" for some purposes:
<br><a href=3D"http://stackoverflow.com/q/14815998/46642" target=3D"_blank"=
>http://stackoverflow.com/q/<wbr>14815998/46642</a>
<br></blockquote><div>As one of the comments pointed out, std::is_construct=
ible checks if there is a constructor, not if there is a well-formed constr=
uctor. The constructor in question is still ill-formed everywhere.<br><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>Now, as far as I can see, the standard makes
<br>std::vector&lt;std::unique_ptr&lt;<wbr>void&gt;&gt; have a copy constru=
ctor, even
<br>though it makes any program that instantiates it ill-formed as a
<br>consequence of its defined semantics. Please correct me if my reading
<br>of the standard here is wrong and makes all of this moot.
<br></blockquote><div><br>I think that's not true, although I agree it is n=
ot obvious.<br><br>Check 23.2.1 [container.requirements.general], table 96,=
 there is a row for expressions with STL container copy constructors:<br><d=
iv style=3D"margin-left: 40px;">X(a) Requires:T is CopyInsertable into X (s=
ee below). post: a =3D=3D X(a).<br></div>CopyInsertable is:<br><div style=
=3D"margin-left: 40px;">in addition to T being MoveInsertable into X, the f=
ollowing expression is well-formed: <span style=3D"font-family: courier new=
,monospace;">allocator_traits&lt;A&gt;::construct(m, p, v)</span> and its e=
valuation causes the following postcondition to hold: The value of v is unc=
hanged and is equivalent to *p.<br></div>For the default allocator (what ca=
lls placement new in construct), it is obvious that this is not true with u=
nique_ptr. It's not that obvious, but you cannot write a custom allocator w=
hat can construct a unique_ptr with the postcondition being valid too.<br><=
br>Thus, the postcondition for X(a) is void, thus it is ill-formed in case =
of vector&lt;unique_ptr&lt;int&gt;&gt;, and for all containers with unique_=
ptr.<br><br>Regards, Robert<br></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_366_30059536.1377305716697--

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 25 Aug 2013 10:54:17 -0700 (PDT)
Raw View
The problem here is simply a library bug, be it the Standard Library or oth=
er. A constructor shouldn't be declared with no available definition. Some =
other places already state "this signature does not participate in overload=
 resolution..." and the principle needs more general application.

If a library defect hasn't been filed, that's the next order of business, b=
ut this may require a paper, too. The fix could be just adding a sentence t=
o the container requirements table.

Concepts simplify introspection a la wellformed() (it's called requires()) =
but it still only applies to immediate context. You don't want the overhead=
 of instantiating a definition during overload resolution, of a function th=
at might never be used.

Implementing SFINAE on a copy constructor is unfortunately harder than it s=
hould be, and I'm not aware of any fix in the pipeline. Two lightweight alt=
ernatives:

1. Implement the constructor in a base, and inherit from another base which=
 is conditionally copy-constructible, so the implicit definition of the der=
ived constructor is conditionally deleted.

2. Use std::conditional to replace the constructor parameter type with a ha=
rmless, unused tag.

--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 25 Aug 2013 11:10:00 -0700 (PDT)
Raw View
On Monday, August 26, 2013 1:54:17 AM UTC+8, David Krauss wrote:
> Implementing SFINAE on a copy constructor is unfortunately harder than it should be, and I'm not aware of any fix in the pipeline.

Referring from Nicol's answer to N3701, Concepts Lite does address the issue by extending SFINAE-style conditional declaration to non-template members.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 25 Aug 2013 20:44:52 -0700 (PDT)
Raw View
------=_Part_109_4304604.1377488692779
Content-Type: text/plain; charset=ISO-8859-1

On Sunday, August 25, 2013 10:54:17 AM UTC-7, David Krauss wrote:
>
> The problem here is simply a library bug, be it the Standard Library or
> other. A constructor shouldn't be declared with no available definition.
> Some other places already state "this signature does not participate in
> overload resolution..." and the principle needs more general application.
>
> If a library defect hasn't been filed, that's the next order of business,
> but this may require a paper, too. The fix could be just adding a sentence
> to the container requirements table.
>
> Concepts simplify introspection a la wellformed() (it's called requires())
> but it still only applies to immediate context. You don't want the overhead
> of instantiating a definition during overload resolution, of a function
> that might never be used.
>
But no such definition is being instantiated. That's *the point*. It sees
that there's a function with a compatible signature, but that function has
a requires clause. So it evaluates the requires clause, and if everything
checks out, *then* it may go on and use that function. But nothing gets
instantiated unless the requires checks out.


> Implementing SFINAE on a copy constructor is unfortunately harder than it
> should be, and I'm not aware of any fix in the pipeline. Two lightweight
> alternatives:
>
> 1. Implement the constructor in a base, and inherit from another base
> which is conditionally copy-constructible, so the implicit definition of
> the derived constructor is conditionally deleted.
>
2. Use std::conditional to replace the constructor parameter type with a
> harmless, unused tag.
>
And what happens if you instantiate std::vector with values of this
"harmless, unused tag" type?

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_109_4304604.1377488692779
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, August 25, 2013 10:54:17 AM UTC-7, David Krauss=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The problem here is sim=
ply a library bug, be it the Standard Library or other. A constructor shoul=
dn't be declared with no available definition. Some other places already st=
ate "this signature does not participate in overload resolution..." and the=
 principle needs more general application.<p>If a library defect hasn't bee=
n filed, that's the next order of business, but this may require a paper, t=
oo. The fix could be just adding a sentence to the container requirements t=
able.</p><p>Concepts simplify introspection a la wellformed() (it's called =
requires()) but it still only applies to immediate context. You don't want =
the overhead of instantiating a definition during overload resolution, of a=
 function that might never be used.<br></p></blockquote><div>But no such de=
finition is being instantiated. That's <i>the point</i>. It sees that there=
's a function with a compatible signature, but that function has a requires=
 clause. So it evaluates the requires clause, and if everything checks out,=
 <i>then</i> it may go on and use that function. But nothing gets instantia=
ted unless the requires checks out.<br>&nbsp;</div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><p>Implementing SFINAE on a copy constructor is unfort=
unately harder than it should be, and I'm not aware of any fix in the pipel=
ine. Two lightweight alternatives:</p><p>1. Implement the constructor in a =
base, and inherit from another base which is conditionally copy-constructib=
le, so the implicit definition of the derived constructor is conditionally =
deleted.&nbsp;</p></blockquote><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><p>2. Use std::conditional to replace the constructor parameter type with =
a harmless, unused tag.<br></p></blockquote><div>And what happens if you in=
stantiate std::vector with values of this "harmless, unused tag" type? <br>=
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_109_4304604.1377488692779--

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 25 Aug 2013 22:00:57 -0700 (PDT)
Raw View
The tag would be private and use a reserved name. Point is, the declaration would exist but be hidden. The other approach is less hackish.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.