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


Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Sat, 24 Aug 2013 03:22:34 +0200
Raw View
(Ooops, it appears that R=F3bert sent the message original only to me,
and when I blindly replied to that message, it obviously didn't go to
the list; here it goes again)

On Sat, Aug 24, 2013 at 2:23 AM, R=F3bert D=E1vid <lrdxgm@gmail.com> wrote:
>
>
> 2013. augusztus 23., p=E9ntek 16:08:51 UTC+2 id=F5pontban R. Martinho Fer=
nandes
> a k=F6vetkez=F5t =EDrta:
>>
>> 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
>
> Check David Rodr=EDguez - dribeas' comment to the first answer here, I th=
ink
> that should been the answer to the SO question: is_constructible checks i=
f
> there is a constructor, not if there is a well-formed constructor.

First of all, I fail to see how that is useful at all.

And second, the *standard* says it checks if a variable definition
that uses passes parameters of the given types to the constructor is
well-formed *but only considering the immediate context*. That kinda
makes the trait useless, if you ask me, because, as with the example
with the vector template, it requires some boilerplate in the
implementation of the template to make sure the trait won't be
misleading.

I think that traits that "lie" are a serious issue: if you write code
that uses an optimised version depending on some operation being
available, and falls back to an unoptimised one otherwise (for
example, using tag dispatching), that code will pick the "optimised"
but ill-formed version when it could have picked the unoptimised but
well-formed version. Either library writers have to write boilerplate
on all their classes to make sure no trait ends up "lying" like this,
or clients have get errors when the code should have compiled. No one
wins.

>> 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.
>
>
> I think this is not true, although I agree it is not obvious.
>
> If you check 23.2.1 [container.requirements.general], table 96 has two ro=
ws
> for copy construction of containers, and it does add a requirement:
>
> X(a) Requires:T is CopyInsertable into X (see below). post: a =3D=3D X(a)=
..

Requires paragraphs don't remove overloads from candidate sets. They
result in undefined behaviour when violated (=A717.6.4.11), unless a
Throws paragraph specifies an exception.

> Which standard library implementation does have a copy constructor for
> vector<unique_ptr<int>> (just ill-formed, like in the SO question)?

All of those I know: libstdc++, libc++, and the one that comes with
MSVC. They have one because they implement vector in a manner not
dissimilar to the following, for the bits that concern us here (which
also happens to be just as shown in the standard synopsis at
=A723.3.6.1):

template <typename T>
class vector {
    //... blah blah ...
    vector(const vector& x) : /* blah */ {
        // blah
    }
    //... blah blah ...
};

The constructor is there, and when only an **immediate context** is
considered, an expression that uses can be considered well-formed (see
executable code sample I linked to in the original post
http://coliru.stacked-crooked.com/view?id=3D735d0e4868baddb9fa210cbf18ca02e=
7-f0bd80647c520ac4f6fb0347af37c64b)

For what is worth, the wording that used is by the standard to remove
an overload from a candidate set is as follows:

> Remark: This constructor shall not participate in overload resolution
> unless each type in UTypes is implicitly convertible to its
> corresponding type in Types.

(this example from =A720.4.2.1, paragraph 10; part of the description of
`template <class... UTypes> explicit constexpr tuple(UTypes&&... u);`)

Still, even if all of this is false and the standard does indeed
remove the vector's copy constructor from overload resolution somehow
(something that doesn't happen in practice), library writers in
general still have to write boilerplate code with std::enable_if if
they want their classes to be as well-behaved as those in the standard
library.



Mit freundlichen Gr=FC=DFen,

Martinho
Mit freundlichen Gr=FC=DFen,

Martinho


On Sat, Aug 24, 2013 at 2:55 AM, R=F3bert D=E1vid <lrdxgm@gmail.com> wrote:
> (Google's editor seems to eat my previous answer, if it didn't and was ju=
st
> delayed, then sorry for the double post)
>
>
> 2013. augusztus 23., p=E9ntek 16:08:51 UTC+2 id=F5pontban R. Martinho Fer=
nandes
> a k=F6vetkez=F5t =EDrta:
>>
>> 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
>
> As one of the comments pointed out, std::is_constructible checks if there=
 is
> a constructor, not if there is a well-formed constructor. The constructor=
 in
> question is still ill-formed everywhere.
>
>>
>> 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.
>
>
> 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 f=
or
> 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
> well-formed: allocator_traits<A>::construct(m, p, v) and its evaluation
> causes the following postcondition to hold: The value of v is unchanged a=
nd
> is equivalent to *p.
> For the default allocator (what calls placement new in construct), it is
> obvious that this is not true with unique_ptr. It's not that obvious, but
> you cannot write a custom allocator what can construct a unique_ptr with =
the
> postcondition being valid too.
>
> Thus, the postcondition for X(a) is void, thus it is ill-formed in case o=
f
> vector<unique_ptr<int>>, and for all containers with unique_ptr.
>
> Regards, Robert
>
> --
>
> ---
> 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/.

--=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: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 24 Aug 2013 00:53:42 -0700 (PDT)
Raw View
------=_Part_393_17907577.1377330822259
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

On Friday, August 23, 2013 6:22:34 PM UTC-7, R. Martinho Fernandes wrote:
>
> (Ooops, it appears that R=F3bert sent the message original only to me,=20
> and when I blindly replied to that message, it obviously didn't go to=20
> the list; here it goes again)=20
>
> On Sat, Aug 24, 2013 at 2:23 AM, R=F3bert D=E1vid <lrd...@gmail.com<javas=
cript:>>=20
> wrote:=20
> >=20
> >=20
> > 2013. augusztus 23., p=E9ntek 16:08:51 UTC+2 id=F5pontban R. Martinho=
=20
> Fernandes=20
> > a k=F6vetkez=F5t =EDrta:=20
> >>=20
> >> 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
> >=20
> > Check David Rodr=EDguez - dribeas' comment to the first answer here, I=
=20
> think=20
> > that should been the answer to the SO question: is_constructible checks=
=20
> if=20
> > there is a constructor, not if there is a well-formed constructor.=20
>
> First of all, I fail to see how that is useful at all.=20
>
> And second, the *standard* says it checks if a variable definition=20
> that uses passes parameters of the given types to the constructor is=20
> well-formed *but only considering the immediate context*. That kinda=20
> makes the trait useless, if you ask me, because, as with the example=20
> with the vector template, it requires some boilerplate in the=20
> implementation of the template to make sure the trait won't be=20
> misleading.=20
>
> I think that traits that "lie" are a serious issue: if you write code=20
> that uses an optimised version depending on some operation being=20
> available, and falls back to an unoptimised one otherwise (for=20
> example, using tag dispatching), that code will pick the "optimised"=20
> but ill-formed version when it could have picked the unoptimised but=20
> well-formed version. Either library writers have to write boilerplate=20
> on all their classes to make sure no trait ends up "lying" like this,=20
> or clients have get errors when the code should have compiled. No one=20
> wins.
>

Well yes, but that's not going to change either.

Traits are incapable of not "lying", since they can't actually know if a=20
function call can truly work. They can only detect if such a function *
exists* to be called. There's no real fix for that.

The only way to deal with the issue is to write that "boilerplace" so that=
=20
functions stop existing if you instantiate the class/function with a type=
=20
that doesn't provide the expected interface. I would guess that the reason=
=20
the standard doesn't require std::vector implementations to write that=20
boilerplate is because it could negatively impact compile times.=20
std::enable_if isn't a small thing, and checking type traits for complex=20
things like whether something is copy-constructible is also less than fast.

Fortunately, concepts provides a pretty braindead simple way of doing this,=
=20
which much like variadic templates should help make compile times=20
reasonable while still providing these features.

--=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_393_17907577.1377330822259
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, August 23, 2013 6:22:34 PM UTC-7, R. Martinho F=
ernandes wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(Ooops, it appe=
ars that R=F3bert sent the message original only to me,
<br>and when I blindly replied to that message, it obviously didn't go to
<br>the list; here it goes again)
<br>
<br>On Sat, Aug 24, 2013 at 2:23 AM, R=F3bert D=E1vid &lt;<a href=3D"javasc=
ript:" target=3D"_blank" gdf-obfuscated-mailto=3D"6w61sI7Pao4J">lrd...@gmai=
l.com</a>&gt; wrote:
<br>&gt;
<br>&gt;
<br>&gt; 2013. augusztus 23., p=E9ntek 16:08:51 UTC+2 id=F5pontban R. Marti=
nho Fernandes
<br>&gt; a k=F6vetkez=F5t =EDrta:
<br>&gt;&gt;
<br>&gt;&gt; First of all, let's make sure we are all aware of the fact tha=
t an
<br>&gt;&gt; expression that would normally be ill-formed may still count a=
s
<br>&gt;&gt; "well-formed" for some purposes:
<br>&gt;&gt; <a href=3D"http://stackoverflow.com/q/14815998/46642" target=
=3D"_blank">http://stackoverflow.com/q/<wbr>14815998/46642</a>
<br>&gt;
<br>&gt; Check David Rodr=EDguez - dribeas' comment to the first answer her=
e, I think
<br>&gt; that should been the answer to the SO question: is_constructible c=
hecks if
<br>&gt; there is a constructor, not if there is a well-formed constructor.
<br>
<br>First of all, I fail to see how that is useful at all.
<br>
<br>And second, the *standard* says it checks if a variable definition
<br>that uses passes parameters of the given types to the constructor is
<br>well-formed *but only considering the immediate context*. That kinda
<br>makes the trait useless, if you ask me, because, as with the example
<br>with the vector template, it requires some boilerplate in the
<br>implementation of the template to make sure the trait won't be
<br>misleading.
<br>
<br>I think that traits that "lie" are a serious issue: if you write code
<br>that uses an optimised version depending on some operation being
<br>available, and falls back to an unoptimised one otherwise (for
<br>example, using tag dispatching), that code will pick the "optimised"
<br>but ill-formed version when it could have picked the unoptimised but
<br>well-formed version. Either library writers have to write boilerplate
<br>on all their classes to make sure no trait ends up "lying" like this,
<br>or clients have get errors when the code should have compiled. No one
<br>wins.<br></blockquote><div><br>Well yes, but that's not going to change=
 either.<br><br>Traits are incapable of not "lying", since they can't actua=
lly know if a function call can truly work. They can only detect if such a =
function <i>exists</i> to be called. There's no real fix for that.<br><br>T=
he only way to deal with the issue is to write that "boilerplace" so that f=
unctions stop existing if you instantiate the class/function with a type th=
at doesn't provide the expected interface. I would guess that the reason th=
e standard doesn't require std::vector implementations to write that boiler=
plate is because it could negatively impact compile times. std::enable_if i=
sn't a small thing, and checking type traits for complex things like whethe=
r something is copy-constructible is also less than fast.<br><br>Fortunatel=
y, concepts provides a pretty braindead simple way of doing this, which muc=
h like variadic templates should help make compile times reasonable while s=
till providing these features.<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_393_17907577.1377330822259--

.


Author: Martinho Fernandes <martinho.fernandes@gmail.com>
Date: Sun, 25 Aug 2013 02:47:22 +0200
Raw View
On Sat, Aug 24, 2013 at 9:53 AM, Nicol Bolas <jmckesson@gmail.com> wrote:
> Traits are incapable of not "lying", since they can't actually know if a
> function call can truly work. They can only detect if such a function exists
> to be called. There's no real fix for that.

Well, can concepts?

> The only way to deal with the issue is to write that "boilerplace" so that
> functions stop existing if you instantiate the class/function with a type
> that doesn't provide the expected interface. I would guess that the reason
> the standard doesn't require std::vector implementations to write that
> boilerplate is because it could negatively impact compile times.
> std::enable_if isn't a small thing, and checking type traits for complex
> things like whether something is copy-constructible is also less than fast.

For what little it is worth, it can be done without enable_if (by
inheriting from base classes with specialisations). I honestly don't
understand why checking if something is copy constructible is slow,
especially if when said check happens you will likely try to use the
copy constructor anyway (and thus it will need to instantiated
anyway).

> Fortunately, concepts provides a pretty braindead simple way of doing this,
> which much like variadic templates should help make compile times reasonable
> while still providing these features.

What makes checking this with concepts fast?

--

---
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: Sat, 24 Aug 2013 22:24:30 -0700 (PDT)
Raw View
------=_Part_859_27470848.1377408270750
Content-Type: text/plain; charset=ISO-8859-1



On Saturday, August 24, 2013 5:47:22 PM UTC-7, R. Martinho Fernandes wrote:
>
> On Sat, Aug 24, 2013 at 9:53 AM, Nicol Bolas <jmck...@gmail.com<javascript:>>
> wrote:
> > Traits are incapable of not "lying", since they can't actually know if a
> > function call can truly work. They can only detect if such a function
> exists
> > to be called. There's no real fix for that.
>
> Well, can concepts?
>
> > The only way to deal with the issue is to write that "boilerplace" so
> that
> > functions stop existing if you instantiate the class/function with a
> type
> > that doesn't provide the expected interface. I would guess that the
> reason
> > the standard doesn't require std::vector implementations to write that
> > boilerplate is because it could negatively impact compile times.
> > std::enable_if isn't a small thing, and checking type traits for complex
> > things like whether something is copy-constructible is also less than
> fast.
>
> For what little it is worth, it can be done without enable_if (by
> inheriting from base classes with specialisations). I honestly don't
> understand why checking if something is copy constructible is slow,
> especially if when said check happens you will likely try to use the
> copy constructor anyway (and thus it will need to instantiated
> anyway).
>
> > Fortunately, concepts provides a pretty braindead simple way of doing
> this,
> > which much like variadic templates should help make compile times
> reasonable
> > while still providing these features.
>
> What makes checking this with concepts fast?
>

Because it'll be in a form that's not a big, giant hack.

To do this with current technology, you have to employ several template
metaprogramming templates. You have to exploit SFINAE to stop the compiler
from instantiating the template without an error. For a constructor like
this one, you would have to do something like this:

template<typename T>
class vector
{
    vector(const Tester &other, std::enable_if<std::is_copy_constructible<T
>::value, int>::type r = 0)
    {
    }
};


In order for the compiler to check this, it has to instantiate
`is_copy_constructible` (which admittedly may be some kind of compiler
intrinsic), then instantiate `enable_if` with the result of that and int.
In that instantiation, `enable_if` will fail if the value of the first one
is false, so now the compiler has to say that there was a substitution
failure and thus exit.

With concepts, this looks like this:

template<typename T>
class Tester
{
    requires (T t){ {T(t);} }
    Tester(const Tester &other)
    {
    }
};

Here, the compiler knows up front what's going on. You're not relying on
template metaprogramming; you're directly interfacing with the compiler and
telling it *exactly* what you want to do. The compiler knows that this
function may or may not be instantiated based on a requires clause. It can
process this requires clause into a form that is much more easily
digestible when it comes time to instantiate the function. And so forth.

The compiler knows what you're doing and can therefore optimize it down to
whatever is fastest to test. There is no instantiation of random templates
or traits or anything. There's no piggy-backing off of SFINAE or other
parameter stuff. The compiler has all of the information about what's going
on; it isn't being tricked into doing things right.

There's no way that this *doesn't* speed up compilation time of these kinds
of constraints. At least, given that compiler writers want to spend the
time to do so. Even if the compiler simply turned these into the enable_if
version internally, it would only be equally as slow.

Also, there have been tests on the first version of concepts-lite that show
that these kinds of compiler intrinsics are *vital* for concepts
performance.

--

---
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_859_27470848.1377408270750
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, August 24, 2013 5:47:22 PM UTC-7, R. =
Martinho Fernandes wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sa=
t, Aug 24, 2013 at 9:53 AM, Nicol Bolas &lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"Jsv0rmQJ-QoJ">jmck...@gmail.com</a>&gt=
; wrote:
<br>&gt; Traits are incapable of not "lying", since they can't actually kno=
w if a
<br>&gt; function call can truly work. They can only detect if such a funct=
ion exists
<br>&gt; to be called. There's no real fix for that.
<br>
<br>Well, can concepts?
<br>
<br>&gt; The only way to deal with the issue is to write that "boilerplace"=
 so that
<br>&gt; functions stop existing if you instantiate the class/function with=
 a type
<br>&gt; that doesn't provide the expected interface. I would guess that th=
e reason
<br>&gt; the standard doesn't require std::vector implementations to write =
that
<br>&gt; boilerplate is because it could negatively impact compile times.
<br>&gt; std::enable_if isn't a small thing, and checking type traits for c=
omplex
<br>&gt; things like whether something is copy-constructible is also less t=
han fast.
<br>
<br>For what little it is worth, it can be done without enable_if (by
<br>inheriting from base classes with specialisations). I honestly don't
<br>understand why checking if something is copy constructible is slow,
<br>especially if when said check happens you will likely try to use the
<br>copy constructor anyway (and thus it will need to instantiated
<br>anyway).
<br>
<br>&gt; Fortunately, concepts provides a pretty braindead simple way of do=
ing this,
<br>&gt; which much like variadic templates should help make compile times =
reasonable
<br>&gt; while still providing these features.
<br>
<br>What makes checking this with concepts fast?<br></blockquote><div><br>B=
ecause it'll be in a form that's not a big, giant hack.<br><br>To do this w=
ith current technology, you have to employ several template metaprogramming=
 templates. You have to exploit SFINAE to stop the compiler from instantiat=
ing the template without an error. For a constructor like this one, you wou=
ld have to do something like this:<br><br><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
vector<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp=
; &nbsp; vector</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cons=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Tester</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">other</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">enable_if</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">is_copy_con=
structible</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">value</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&gt;::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">type r </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &n=
bsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nb=
sp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div></code>=
</div><br>In order for the compiler to check this, it has to instantiate `i=
s_copy_constructible` (which admittedly may be some kind of compiler intrin=
sic), then instantiate `enable_if` with the result of that and int. In that=
 instantiation, `enable_if` will fail if the value of the first one is fals=
e, so now the compiler has to say that there was a substitution failure and=
 thus exit.<br><br>With concepts, this looks like this:<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Tester</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp; requires </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">T t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">){<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">t</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">);}</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&=
nbsp; &nbsp; </span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Tester</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Tester</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">other</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">};</span></div></code></div><br>Here, the compiler knows up fron=
t what's going on. You're not relying on template metaprogramming; you're d=
irectly interfacing with the compiler and telling it <i>exactly</i> what yo=
u want to do. The compiler knows that this function may or may not be insta=
ntiated based on a requires clause. It can process this requires clause int=
o a form that is much more easily digestible when it comes time to instanti=
ate the function. And so forth.<br><br>The compiler knows what you're doing=
 and can therefore optimize it down to whatever is fastest to test. There i=
s no instantiation of random templates or traits or anything. There's no pi=
ggy-backing off of SFINAE or other parameter stuff. The compiler has all of=
 the information about what's going on; it isn't being tricked into doing t=
hings right.<br><br>There's no way that this <i>doesn't</i> speed up compil=
ation time of these kinds of constraints. At least, given that compiler wri=
ters want to spend the time to do so. Even if the compiler simply turned th=
ese into the enable_if version internally, it would only be equally as slow=
..<br><br>Also, there have been tests on the first version of concepts-lite =
that show that these kinds of compiler intrinsics are <i>vital</i> for conc=
epts performance.<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_859_27470848.1377408270750--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Sun, 25 Aug 2013 17:10:45 -0500
Raw View
--001a11c1e998bbba9204e4cceb3e
Content-Type: text/plain; charset=ISO-8859-1

On 25 August 2013 12:54, David Krauss <potswa@gmail.com> wrote:

>
> If a library defect hasn't been filed,


I don't believe it is a defect; it's a feature request.  Such functionality
was never intended in C++98, C++03, C++11 or C++14.


> 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.
>

Don't kid yourself.  It's a *huge* change (if not to the standard, then
certainly to implementations), as the issue isn't just for constructors.
 For instance, operator== shouldn't exist for vector<T> if it doesn't exist
for T.  Etc., etc.

I don't see this getting addressed until after we have concepts.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.

--001a11c1e998bbba9204e4cceb3e
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra">On 25 August 2013 12:54, David =
Krauss <span dir=3D"ltr">&lt;<a href=3D"mailto:potswa@gmail.com" target=3D"=
_blank">potswa@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex">

<br>
If a library defect hasn&#39;t been filed,</blockquote><div><br></div><div>=
I don&#39;t believe it is a defect; it&#39;s a feature request. =A0Such fun=
ctionality was never intended in C++98, C++03, C++11 or C++14.</div><div>

=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"> that&#39;s the next order of busin=
ess, but this may require a paper, too. The fix could be just adding a sent=
ence to the container requirements table.<br>

</blockquote><div><br></div><div>Don&#39;t kid yourself. =A0It&#39;s a *hug=
e* change (if not to the standard, then certainly to implementations), as t=
he issue isn&#39;t just for constructors. =A0For instance, operator=3D=3D s=
houldn&#39;t exist for vector&lt;T&gt; if it doesn&#39;t exist for T. =A0Et=
c., etc.</div>

<div><br></div><div>I don&#39;t see this getting addressed until after we h=
ave concepts.</div></div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailt=
o:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@evilove=
rlord.com</a>&gt;=A0 (847) 691-1404
</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 />

--001a11c1e998bbba9204e4cceb3e--

.


Author: David Krauss <potswa@gmail.com>
Date: Sun, 25 Aug 2013 22:19:54 -0700 (PDT)
Raw View
The current spec doesn't disallow container constructor SFINAE. Maybe I'm m=
istaken but it looks like is_copy_constructible<container<MoveOnlyT>> is im=
plementation-defined. That's enough to qualify as a defect. The problem is =
thus new to C++11 and specific to signatures that determine trait values.

What traits the user may define by checking for signature existence are ano=
ther matter. With concepts, implementations may endeavor to eliminate every=
 declaration without a well-formed definition, but that's another story. Co=
nsistency of standard traits should be a reasonable goal for now.

--=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 22:26:25 -0700 (PDT)
Raw View
The current spec doesn't disallow container constructor SFINAE. Maybe I'm m=
istaken but it looks like is_copy_constructible<container<MoveOnlyT>> is im=
plementation-defined. That's enough to qualify as a defect. The problem is =
thus new to C++11 and specific to signatures that determine trait values.

What traits the user may define by checking for signature existence are ano=
ther matter. With concepts, implementations may endeavor to eliminate every=
 declaration without a well-formed definition, but that's another story. Co=
nsistency of standard traits should be a reasonable goal for now.

--=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 22:26:27 -0700 (PDT)
Raw View
The current spec doesn't disallow container constructor SFINAE. Maybe I'm m=
istaken but it looks like is_copy_constructible<container<MoveOnlyT>> is im=
plementation-defined. That's enough to qualify as a defect. The problem is =
thus new to C++11 and specific to signatures that determine trait values.

What traits the user may define by checking for signature existence are ano=
ther matter. With concepts, implementations may endeavor to eliminate every=
 declaration without a well-formed definition, but that's another story. Co=
nsistency of standard traits should be a reasonable goal for now.

--=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/.

.