Topic: Why are concepts restricted to namespace-scope?


Author: Justin Bassett <jbassett271@gmail.com>
Date: Wed, 8 Aug 2018 22:07:24 -0700 (PDT)
Raw View
------=_Part_140_483942083.1533791244453
Content-Type: multipart/alternative;
 boundary="----=_Part_141_1148879740.1533791244453"

------=_Part_141_1148879740.1533791244453
Content-Type: text/plain; charset="UTF-8"

I recently discovered that concepts must be defined at namespace scope.
What is the reason for this? It seems like an arbitrary restriction to me,
when alias templates and variable templates can appear at class scope.

This realization came from thinking about passing concepts as template
parameters. It currently is not possible. Template parameters can't be
concepts; they can only be template template (type) parameters, type
parameters, or value parameters. Wrapping the concept inside a struct
doesn't work as well, since the concept must be defined at namespace scope.

--
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/3825544b-b617-4a0e-a02d-a5041d989c15%40isocpp.org.

------=_Part_141_1148879740.1533791244453
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I recently discovered that concepts must be defined at nam=
espace scope. What is the reason for this? It seems like an arbitrary restr=
iction to me, when alias templates and variable templates can appear at cla=
ss scope.<div><br></div><div>This realization came from thinking about pass=
ing concepts as template parameters. It currently is not possible. Template=
 parameters can&#39;t be concepts; they can only be template template (type=
) parameters, type parameters, or value parameters. Wrapping the concept in=
side a struct doesn&#39;t work as well, since the concept must be defined a=
t namespace scope.</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/3825544b-b617-4a0e-a02d-a5041d989c15%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3825544b-b617-4a0e-a02d-a5041d989c15=
%40isocpp.org</a>.<br />

------=_Part_141_1148879740.1533791244453--

------=_Part_140_483942083.1533791244453--

.


Author: gmisocpp@gmail.com
Date: Wed, 8 Aug 2018 22:58:48 -0700 (PDT)
Raw View
------=_Part_193_1254071581.1533794328137
Content-Type: multipart/alternative;
 boundary="----=_Part_194_2013402397.1533794328137"

------=_Part_194_2013402397.1533794328137
Content-Type: text/plain; charset="UTF-8"



On Thursday, August 9, 2018 at 5:07:24 PM UTC+12, Justin Bassett wrote:
>
> I recently discovered that concepts must be defined at namespace scope.
> What is the reason for this? It seems like an arbitrary restriction to me,
> when alias templates and variable templates can appear at class scope.
>
> This realization came from thinking about passing concepts as template
> parameters. It currently is not possible. Template parameters can't be
> concepts; they can only be template template (type) parameters, type
> parameters, or value parameters. Wrapping the concept inside a struct
> doesn't work as well, since the concept must be defined at namespace scope.
>

It seems to be that concepts are fundamental things. How fundamental is
something if it pertains to just one class?
I don't like the sound of 'burying' a fundamental thing in a class.
I haven't thought about this deeply so I may be wrong, but I would have
been surprised if concepts could be defined in a class. It seem like a bad
idea.
I'm sure somebody will prove me wrong though, so I guess it's could to
raise the question, but that's my 10c feeling on the subject.
Have you got an example use case?

--
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/531fca50-41f5-4702-84b8-1171033616c1%40isocpp.org.

------=_Part_194_2013402397.1533794328137
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, August 9, 2018 at 5:07:24 PM UTC+12, =
Justin Bassett wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px=
 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); b=
order-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr">I recent=
ly discovered that concepts must be defined at namespace scope. What is the=
 reason for this? It seems like an arbitrary restriction to me, when alias =
templates and variable templates can appear at class scope.<div><br></div><=
div>This realization came from thinking about passing concepts as template =
parameters. It currently is not possible. Template parameters can&#39;t be =
concepts; they can only be template template (type) parameters, type parame=
ters, or value parameters. Wrapping the concept inside a struct doesn&#39;t=
 work as well, since the concept must be defined at namespace scope.</div><=
/div></blockquote><div><br></div><div>It seems to be that concepts are fund=
amental things. How fundamental is something if it pertains to just one cla=
ss?</div><div>I don&#39;t like the sound of &#39;burying&#39;=C2=A0a fundam=
ental thing in a class.</div><div>I haven&#39;t thought about this deeply s=
o I may be wrong, but I would have been surprised if concepts could be defi=
ned in a class. It seem like a bad idea.</div><div>I&#39;m sure somebody wi=
ll prove me wrong though, so I guess it&#39;s could to raise the question, =
but that&#39;s my 10c feeling on the subject.</div><div><div>Have you got a=
n example use case?</div></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/531fca50-41f5-4702-84b8-1171033616c1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/531fca50-41f5-4702-84b8-1171033616c1=
%40isocpp.org</a>.<br />

------=_Part_194_2013402397.1533794328137--

------=_Part_193_1254071581.1533794328137--

.


Author: Justin Bassett <jbassett271@gmail.com>
Date: Thu, 9 Aug 2018 00:25:46 -0700
Raw View
--000000000000c745f00572fb8972
Content-Type: text/plain; charset="UTF-8"

On Wed, Aug 8, 2018, 10:58 PM <gmisocpp@gmail.com> wrote:

>
> It seems to be that concepts are fundamental things. How fundamental is
> something if it pertains to just one class?
> I don't like the sound of 'burying' a fundamental thing in a class.
> I haven't thought about this deeply so I may be wrong, but I would have
> been surprised if concepts could be defined in a class. It seem like a bad
> idea.
>
I'm sure somebody will prove me wrong though, so I guess it's could to
> raise the question, but that's my 10c feeling on the subject.
>

It doesn't have to pertain to a single class. You can access he concept
outside of the class, just like with typedefs or static variables. In that
way, a concept could be inside a particular class but actually apply to any
arbitrary type.

Have you got an example use case?
>

I tried to communicate one earlier: passing concepts as template
parameters. There's no concept parameter to go along with type or value
parameters, and since concepts can't be in a struct, the obvious solution
of wrapping in a struct fails.

--
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/CAPuuy5e6fHrzbxZ6A5a%2BwTqhdycyU2_VLWE3R3HdXj6_D2rjrA%40mail.gmail.com.

--000000000000c745f00572fb8972
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
On Wed, Aug 8, 2018, 10:58 PM  &lt;<a href=3D"mailto:gmisocpp@gmail.com">gm=
isocpp@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div><br></div><div>It seems to be that concepts are fundamen=
tal things. How fundamental is something if it pertains to just one class?<=
/div><div>I don&#39;t like the sound of &#39;burying&#39;=C2=A0a fundamenta=
l thing in a class.</div><div>I haven&#39;t thought about this deeply so I =
may be wrong, but I would have been surprised if concepts could be defined =
in a class. It seem like a bad idea.=C2=A0</div></div></blockquote></div></=
div><div dir=3D"auto"><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"><div dir=3D"ltr"><div>I&#39;m sure somebody will prove me wrong though=
, so I guess it&#39;s could to raise the question, but that&#39;s my 10c fe=
eling on the subject.</div></div></blockquote></div></div><div dir=3D"auto"=
><br></div><div dir=3D"auto"><font face=3D"sans-serif">It doesn&#39;t have =
to pertain to a single class. You can access he concept outside of the clas=
s, just like with typedefs or static variables. In that way, a concept coul=
d be inside a particular class but actually apply to any arbitrary type.</f=
ont></div><div dir=3D"auto"><br></div><div dir=3D"auto"><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"><div dir=3D"ltr"><div><div>Have you =
got an example use case?</div></div></div></blockquote></div></div><div dir=
=3D"auto"><br></div><div dir=3D"auto">I tried to communicate one earlier: p=
assing concepts as template parameters. There&#39;s no concept parameter to=
 go along with type or value parameters, and since concepts can&#39;t be in=
 a struct, the obvious solution of wrapping in a struct fails.</div><div di=
r=3D"auto"><br></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/CAPuuy5e6fHrzbxZ6A5a%2BwTqhdycyU2_VLW=
E3R3HdXj6_D2rjrA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5e6fHrzbx=
Z6A5a%2BwTqhdycyU2_VLWE3R3HdXj6_D2rjrA%40mail.gmail.com</a>.<br />

--000000000000c745f00572fb8972--

.


Author: gmisocpp@gmail.com
Date: Thu, 9 Aug 2018 00:38:21 -0700 (PDT)
Raw View
------=_Part_182_949488674.1533800301335
Content-Type: multipart/alternative;
 boundary="----=_Part_183_983466756.1533800301335"

------=_Part_183_983466756.1533800301335
Content-Type: text/plain; charset="UTF-8"


>
> It doesn't have to pertain to a single class. You can access he concept
> outside of the class, just like with typedefs or static variables. In that
> way, a concept could be inside a particular class but actually apply to any
> arbitrary type.
>

If the concept can apply to any arbitrary type (as I would expect it
should) why place it in one particular class?
It seems a namespace is the right place in that case.


>
> Have you got an example use case?
>>
>
> I tried to communicate one earlier: passing concepts as template
> parameters. There's no concept parameter to go along with type or value
> parameters, and since concepts can't be in a struct, the obvious solution
> of wrapping in a struct fails.
>
> I can't imagine having a class conform to conditionally to different
concepts based on parameters but I'm not that imaginative, so I was
expecting an example of this usage not a statement on the desire it should
be possible as an example. I'm sure you might be right somebody might want
to do it, as I said.

--
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/0d623b29-c676-4862-b568-833b517e8d3d%40isocpp.org.

------=_Part_183_983466756.1533800301335
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;"><div dir=3D"auto"><div dir=3D=
"auto"><font face=3D"sans-serif">It doesn&#39;t have to pertain to a single=
 class. You can access he concept outside of the class, just like with type=
defs or static variables. In that way, a concept could be inside a particul=
ar class but actually apply to any arbitrary type.</font></div></div></bloc=
kquote><div><br></div><div>If=C2=A0the concept can apply to any arbitrary t=
ype=C2=A0(as I would expect it should) why place it in one particular class=
?</div><div>It seems a namespace is the right place in that case.</div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px=
 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-le=
ft-width: 1px; border-left-style: solid;"><div dir=3D"auto"><div dir=3D"aut=
o"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bor=
der-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-sty=
le: solid;"><div dir=3D"ltr"><div><div>Have you got an example use case?</d=
iv></div></div></blockquote></div></div><div dir=3D"auto"><br></div><div di=
r=3D"auto">I tried to communicate one earlier: passing concepts as template=
 parameters. There&#39;s no concept parameter to go along with type or valu=
e parameters, and since concepts can&#39;t be in a struct, the obvious solu=
tion of wrapping in a struct fails.</div><div dir=3D"auto"><br></div></div>=
</blockquote><div>I can&#39;t imagine having a class conform to conditional=
ly to different concepts based on parameters but I&#39;m not that imaginati=
ve, so I was expecting an example of this usage not a statement on the desi=
re it should be possible as an example. I&#39;m sure you might be right som=
ebody might want to do it, as I said.</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/0d623b29-c676-4862-b568-833b517e8d3d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0d623b29-c676-4862-b568-833b517e8d3d=
%40isocpp.org</a>.<br />

------=_Part_183_983466756.1533800301335--

------=_Part_182_949488674.1533800301335--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Thu, 9 Aug 2018 15:45:08 -0700 (PDT)
Raw View
------=_Part_530_1280157732.1533854708218
Content-Type: multipart/alternative;
 boundary="----=_Part_531_2043406290.1533854708218"

------=_Part_531_2043406290.1533854708218
Content-Type: text/plain; charset="UTF-8"

I also find it hard to grasp why you would want to templatize on what
concepts a template would use as this implies that the code of the template
would have to adapt to which capabilities the concept offers. But the code
is just text and won't change.

On the other hand, consider specializations. It seems logical that you
should be able to specialize the implementation of a template depending on
which concepts are used. BUT: this is what you do by overloading template
functions with different concepts for their template parameters, so for
functions this is already covered. I don't have enough knowledge of
concepts to say whether you can specialize a class template depending on
which concepts one of its template parameters conforms to. I hope it is
possible and I guess it would be expressed something like:

template<typename T> concept MyConcept { ...requirements... };


template<typename T> struct MyStruct {
    ... base implementation ...
};

// Specialize for MyConcept abiding types.
template<MyConcept T> struct MyStruct<T> {
    ... implementation of MyStruct which requires T to conform to MyConcept
....
};


It's hard to see where a concept template parameter would fit in to this. A
concrete example would be helpful!

But while concept template parameters seem odd I am not against allowing
concepts to be class members. Firstly because it reduces the number of
special rules but also it seems logical if the class has a template
function which puts some requirements on its T, why would we put the
concept defining those requirements on the namespace level? Also, for class
templates it would be interesting to be able to use the template parameters
of the class inside the concept definition, to put requirements on the
template parameters of the class and its template methods.


class MyClass {
    template<typename C> concept IntConstructible {
         requires is_constructible_v<C, int>;
    };


    template <IntConstructible T> fun(T x) {
       T  y = 3;   // Thus T mus be int-constructible
    }
};


I don't see fundamental problems with allowing class scope concepts, but
chances are that there are important reasons to forbid this... someone who
can shoot it down?




Den torsdag 9 augusti 2018 kl. 09:38:21 UTC+2 skrev gmis...@gmail.com:
>
> It doesn't have to pertain to a single class. You can access he concept
>> outside of the class, just like with typedefs or static variables. In that
>> way, a concept could be inside a particular class but actually apply to any
>> arbitrary type.
>>
>
> If the concept can apply to any arbitrary type (as I would expect it
> should) why place it in one particular class?
> It seems a namespace is the right place in that case.
>
>
>>
>> Have you got an example use case?
>>>
>>
>> I tried to communicate one earlier: passing concepts as template
>> parameters. There's no concept parameter to go along with type or value
>> parameters, and since concepts can't be in a struct, the obvious solution
>> of wrapping in a struct fails.
>>
>> I can't imagine having a class conform to conditionally to different
> concepts based on parameters but I'm not that imaginative, so I was
> expecting an example of this usage not a statement on the desire it should
> be possible as an example. I'm sure you might be right somebody might want
> to do it, as I said.
>

--
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/6a23f701-2f70-4999-be7e-03699204668a%40isocpp.org.

------=_Part_531_2043406290.1533854708218
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I also find it hard to grasp why you would want to templat=
ize on what concepts a template would use as this implies that the code of =
the template would have to adapt to which capabilities the concept offers. =
But the code is just text and won&#39;t change.<div><br></div><div>On the o=
ther hand, consider specializations. It seems logical that you should be ab=
le to specialize the implementation of a template depending on which concep=
ts are used. BUT: this is what you do by overloading template functions wit=
h different concepts for their template parameters, so for functions this i=
s already covered. I don&#39;t have enough knowledge of concepts to say whe=
ther you can specialize a class template depending on which concepts one of=
 its template parameters conforms to. I hope it is possible and I guess it =
would be expressed something like:</div><div><br></div><div class=3D"pretty=
print" 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 class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">concept</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">My=
Concept</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">requirements</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br><br><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">template</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">MyStruct</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </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: #008;" class=3D=
"styled-by-prettify">base</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> implementation </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 Specialize for MyConcept abiding types.</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><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: #606;" class=3D"st=
yled-by-prettify">MyConcept</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">MyStruct</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=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"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> implementation of </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">MyStruct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> which requires T to conform to </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">MyConcept</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span></div></code></div><div><br>It&#39;s hard t=
o see where a concept template parameter would fit in to this. A concrete e=
xample would be helpful!</div><div><br></div><div>But while concept templat=
e parameters seem odd I am not against allowing concepts to be class member=
s. Firstly because it reduces the number of special rules but also it seems=
 logical if the class has a template function which puts some requirements =
on its T, why would we put the concept defining those requirements on the n=
amespace level? Also, for class templates it would be interesting to be abl=
e to use the template parameters of the class inside the concept definition=
, to put requirements on the template parameters of the class and its templ=
ate methods.</div><div class=3D"prettyprint" style=3D"background-color: rgb=
(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bor=
der-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br><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"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">MyClass</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span st=
yle=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"c=
olor: #000;" class=3D"styled-by-prettify"> C</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">concept</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">IntConstructible</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>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0requires is_constructible_v</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">C</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: #008;" class=3D"=
styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&gt;;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br><br><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">IntConstructible</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> fun</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">T x</span><spa=
n 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-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0T =C2=A0y </spa=
n><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-prettify">3</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// Thus T mus be int-constructible</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br></span></div></code></div><div><br=
></div><div>I don&#39;t see fundamental problems with allowing class scope =
concepts, but chances are that there are important reasons to forbid this..=
.. someone who can shoot it down?<br><br></div><div><br><div><br><br>Den tor=
sdag 9 augusti 2018 kl. 09:38:21 UTC+2 skrev gmis...@gmail.com:<blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-col=
or:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=
=3D"auto"><div dir=3D"auto"><font face=3D"sans-serif">It doesn&#39;t have t=
o pertain to a single class. You can access he concept outside of the class=
, just like with typedefs or static variables. In that way, a concept could=
 be inside a particular class but actually apply to any arbitrary type.</fo=
nt></div></div></blockquote><div><br></div><div>If=C2=A0the concept can app=
ly to any arbitrary type=C2=A0(as I would expect it should) why place it in=
 one particular class?</div><div>It seems a namespace is the right place in=
 that case.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid"><div dir=3D"auto"><div=
 dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:=
1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-st=
yle:solid"><div dir=3D"ltr"><div><div>Have you got an example use case?</di=
v></div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=
=3D"auto">I tried to communicate one earlier: passing concepts as template =
parameters. There&#39;s no concept parameter to go along with type or value=
 parameters, and since concepts can&#39;t be in a struct, the obvious solut=
ion of wrapping in a struct fails.</div><div dir=3D"auto"><br></div></div><=
/blockquote><div>I can&#39;t imagine having a class conform to conditionall=
y to different concepts based on parameters but I&#39;m not that imaginativ=
e, so I was expecting an example of this usage not a statement on the desir=
e it should be possible as an example. I&#39;m sure you might be right some=
body might want to do it, as I said.</div></div></blockquote></div></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/6a23f701-2f70-4999-be7e-03699204668a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6a23f701-2f70-4999-be7e-03699204668a=
%40isocpp.org</a>.<br />

------=_Part_531_2043406290.1533854708218--

------=_Part_530_1280157732.1533854708218--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 9 Aug 2018 18:53:26 -0700 (PDT)
Raw View
------=_Part_619_833548973.1533866006532
Content-Type: multipart/alternative;
 boundary="----=_Part_620_756421318.1533866006534"

------=_Part_620_756421318.1533866006534
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote:
>
> I recently discovered that concepts must be defined at namespace scope.=
=20
> What is the reason for this? It seems like an arbitrary restriction to me=
,=20
> when alias templates and variable templates can appear at class scope.
>
> This realization came from thinking about passing concepts as template=20
> parameters. It currently is not possible. Template parameters can't be=20
> concepts; they can only be template template (type) parameters, type=20
> parameters, or value parameters. Wrapping the concept inside a struct=20
> doesn't work as well, since the concept must be defined at namespace scop=
e.
>


Here's an example involving "member concept aliases" that I worked up the=
=20
other day on Slack:

struct One {
    template<Red T> static void f(T);
    template<class T> using concept concept_ =3D Red<T>;
};
struct Two {
    template<Blue T> static void f(T);
    template<class T> using concept concept_ =3D Blue<T>;
};

template<class Meta, class T> requires(Meta::template concept_<T>)
void hooray(T t) {
    return Meta::f(t);
}

// ...
hooray<One>(a_red_thing);
hooray<Two>(a_blue_thing);

(It occurred to me that it is very convenient how neither `type` nor=20
`value` is a reserved word in C++; and that it is corresponding unfortunate=
=20
that `concept` *will* be a keyword. Notice the use of `concept_` above.)

Casey Carter pointed out that *almost* the same effect can be achieved via

struct One {
    template<Red T> static void f(T);
};
struct Two {
    template<Blue T> static void f(T);
};

template<class Meta, class T> requires requires (T t) { Meta::f(t); }
void hooray(T t) {
    return Meta::f(t);
}

// ...
hooray<One>(a_red_thing);
hooray<Two>(a_blue_thing);

The difference between the "concept" approach and the "anonymous=20
requires-clause" approach has to do with subsumption rules.
Also, this smells a lot like smuggling a concept (e.g. `Red`) through a=20
function declaration (`One::f`), i.e., a sneaky technical workaround for a=
=20
missing feature in the language, analogous to how we used to have to=20
smuggle variable templates through class templates (e.g. every type-trait=
=20
ever).

If you're willing to forgo subsumption (which I personally am, AFAIK), then=
=20
you can already achieve the goal of "member concepts" by simply rewriting=
=20
all your concepts as plain old variable templates. To the extent that this=
=20
doesn't work, it shows why we might want to add real member concepts and=20
concept aliases. To the extent that this does work, it shows why we don't=
=20
technically need the `concept` keyword at all.

struct One {
    template<Red T> static void f(T);
    template<class T> static constexpr bool concept_ =3D Red<T>;
};
struct Two {
    template<Blue T> static void f(T);
    template<class T> static constexpr bool concept_ =3D Blue<T>;
};

template<class Meta, class T> requires Meta::template concept_<T>
void hooray(T t) {
    return Meta::f(t);
}

// ...
hooray<One>(a_red_thing);
hooray<Two>(a_blue_thing);

Here's the example, complete and compilable.=20
<https://wandbox.org/permlink/ySWp3QWnqWIxylQN>

=E2=80=93Arthur

--=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/93c917bb-1c8d-405d-80e9-4fe036af1a58%40isocpp.or=
g.

------=_Part_620_756421318.1533866006534
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin =
Bassett wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>I recently discovered that concepts must be defined at namespace scope. Wh=
at is the reason for this? It seems like an arbitrary restriction to me, wh=
en alias templates and variable templates can appear at class scope.<div><b=
r></div><div>This realization came from thinking about passing concepts as =
template parameters. It currently is not possible. Template parameters can&=
#39;t be concepts; they can only be template template (type) parameters, ty=
pe parameters, or value parameters. Wrapping the concept inside a struct do=
esn&#39;t work as well, since the concept must be defined at namespace scop=
e.</div></div></blockquote><div><br></div><div><br></div><div>Here&#39;s an=
 example involving &quot;member concept aliases&quot; that I worked up the =
other day on Slack:</div><div><br></div><div><div class=3D"prettyprint" sty=
le=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187,=
 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
uct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">One</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Red</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">static</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</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: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">template</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">us=
ing</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">concept</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> concept_ </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">Red</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&gt;;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Two</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><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: #606;"=
 class=3D"styled-by-prettify">Blue</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"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #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"><br>=C2=A0 =C2=A0 </span><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">class</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">usin=
g</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">concept</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> concept_ </span><spa=
n 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=
: #606;" class=3D"styled-by-prettify">Blue</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&gt;;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">temp=
late</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Meta</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> requires</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Meta=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">template</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> concept_</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=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: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> hooray</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">T t</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Meta</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">t</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// ...</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>hooray</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">One</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">a_red_thing</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>hooray</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Two</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">a_blue_thing</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">);</span></div></code></div><div><br></div></div><div>(It occ=
urred to me that it is very convenient how neither `type` nor `value` is a =
reserved word in C++; and that it is corresponding unfortunate that `concep=
t` <i>will</i> be a keyword. Notice the use of `concept_` above.)</div><div=
><br></div><div>Casey Carter pointed out that <i>almost</i> the same effect=
 can be achieved via</div><div><br></div><div><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187=
, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">st=
ruct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">One</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Red</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</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;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Two</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Blue</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">static</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n 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"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br><br></span><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"st=
yled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Meta</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: #008;" class=3D"styled-by-prettify">class</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> requires requires </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">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><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Met=
a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">f</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #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"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> hoora=
y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">T t</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">Meta</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><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"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// ...</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>hooray</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">One</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">a_red_thing</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>hooray</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Two</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">a_blue_thing</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span></div>=
</code></div><div><br></div></div><div>The difference between the &quot;con=
cept&quot; approach and the &quot;anonymous requires-clause&quot; approach =
has to do with subsumption rules.</div><div>Also, this smells a lot like sm=
uggling a concept (e.g. `Red`) through a function declaration (`One::f`), i=
..e., a sneaky technical workaround for a missing feature in the language, a=
nalogous to how we used to have to smuggle variable templates through class=
 templates (e.g. every type-trait ever).</div><div><br></div><div>If you&#3=
9;re willing to forgo subsumption (which I personally am, AFAIK), then you =
can already achieve the goal of &quot;member concepts&quot; by simply rewri=
ting all your concepts as plain old variable templates. To the extent that =
this doesn&#39;t work, it shows why we might want to add real member concep=
ts and concept aliases. To the extent that this does work, it shows why we =
don&#39;t technically need the `concept` keyword at all.</div><div><br></di=
v><div><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, =
250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">One</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Red<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">static</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">te=
mplate</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">static</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">bool</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> concept_ </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Red</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">Two</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">templa=
te</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #606;" class=3D"styled-by-prettify">Blue</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">static</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">template</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">static</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
concept_ </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: #606;" class=3D"styled-by-prettify">Blue</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #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: #660;" cl=
ass=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">template</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Meta<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> requires </span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Meta</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">template</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> concept_</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> hooray</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">T t</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Meta</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</span><s=
pan 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"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-=
by-prettify">// ...</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>hooray</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">One</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a_red_thi=
ng</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>hooray</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #606;" class=3D"styled-by-prettify">Two</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">a_blue_thing</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">);</span></div></code></div><di=
v><br></div></div><div><a href=3D"https://wandbox.org/permlink/ySWp3QWnqWIx=
ylQN">Here&#39;s the example, complete and compilable.</a></div><div><br></=
div><div>=E2=80=93Arthur</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/93c917bb-1c8d-405d-80e9-4fe036af1a58%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/93c917bb-1c8d-405d-80e9-4fe036af1a58=
%40isocpp.org</a>.<br />

------=_Part_620_756421318.1533866006534--

------=_Part_619_833548973.1533866006532--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 9 Aug 2018 19:32:22 -0700 (PDT)
Raw View
------=_Part_640_62721180.1533868342334
Content-Type: multipart/alternative;
 boundary="----=_Part_641_772313265.1533868342334"

------=_Part_641_772313265.1533868342334
Content-Type: text/plain; charset="UTF-8"



On Thursday, August 9, 2018 at 9:53:26 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote:
>>
>> I recently discovered that concepts must be defined at namespace scope.
>> What is the reason for this? It seems like an arbitrary restriction to me,
>> when alias templates and variable templates can appear at class scope.
>>
>> This realization came from thinking about passing concepts as template
>> parameters. It currently is not possible. Template parameters can't be
>> concepts; they can only be template template (type) parameters, type
>> parameters, or value parameters. Wrapping the concept inside a struct
>> doesn't work as well, since the concept must be defined at namespace scope.
>>
>
>
> Here's an example involving "member concept aliases" that I worked up the
> other day on Slack:
>
> struct One {
>     template<Red T> static void f(T);
>     template<class T> using concept concept_ = Red<T>;
> };
> struct Two {
>     template<Blue T> static void f(T);
>     template<class T> using concept concept_ = Blue<T>;
> };
>
> template<class Meta, class T> requires(Meta::template concept_<T>)
> void hooray(T t) {
>     return Meta::f(t);
> }
>
> // ...
> hooray<One>(a_red_thing);
> hooray<Two>(a_blue_thing);
>
>
I don't really see the point in doing that. You're not providing better
error messages, and you're not really providing better documentation of
anything. `Meta::f` is perfectly capable of having concept constraints
written into it, and all `hooray` is doing is passing a value to that
function. So why does `hooray` need to mimic the constraints of `Meta::f`?

--
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/6648df17-d00c-400f-a698-2b3ed968efdb%40isocpp.org.

------=_Part_641_772313265.1533868342334
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, August 9, 2018 at 9:53:26 PM UTC-4, A=
rthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Basset=
t wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I recently=
 discovered that concepts must be defined at namespace scope. What is the r=
eason for this? It seems like an arbitrary restriction to me, when alias te=
mplates and variable templates can appear at class scope.<div><br></div><di=
v>This realization came from thinking about passing concepts as template pa=
rameters. It currently is not possible. Template parameters can&#39;t be co=
ncepts; they can only be template template (type) parameters, type paramete=
rs, or value parameters. Wrapping the concept inside a struct doesn&#39;t w=
ork as well, since the concept must be defined at namespace scope.</div></d=
iv></blockquote><div><br></div><div><br></div><div>Here&#39;s an example in=
volving &quot;member concept aliases&quot; that I worked up the other day o=
n Slack:</div><div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><=
span style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><=
span style=3D"color:#606">One</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:#008">template</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#606">Red</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">static</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">void</span><span style=3D"color:#000"> =
f</span><span style=3D"color:#660">(</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">using</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">concept</span><span styl=
e=3D"color:#000"> concept_ </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">Red</span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span sty=
le=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#660">};</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#008">struct</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#606">Two</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#606">Blue</span><span style=3D"color:#000"> T</=
span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">static</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">void</span><span style=3D"color:#000"> f</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">T</span><sp=
an style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">template</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color=
:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">using</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">concept</span><span style=3D"color:=
#000"> concept_ </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> </span><span style=3D"color:#606">Blue</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"colo=
r:#660">&gt;;</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#660">};</span><span style=3D"color:#000"><br><br></span><span style=3D=
"color:#008">template</span><span style=3D"color:#660">&lt;</span><span sty=
le=3D"color:#008">class</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#606">Meta</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"> requires</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#606">Meta</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> concept_</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><=
span style=3D"color:#660">&gt;)</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#008">void</span><span style=3D"color:#000"> hooray</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">T t</spa=
n><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">return</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#606">Meta</span><span style=3D"color:#660"=
>::</span><span style=3D"color:#000">f</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000">t</span><span style=3D"color:#660">);</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><=
span style=3D"color:#000"><br><br></span><span style=3D"color:#800">// ...<=
/span><span style=3D"color:#000"><br>hooray</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#606">One</span><span style=3D"color:#660=
">&gt;(</span><span style=3D"color:#000">a_red_thing</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br>hooray</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#606">Two</span><span style=
=3D"color:#660">&gt;(</span><span style=3D"color:#000">a_blue_thing</span><=
span style=3D"color:#660">);</span></div></code></div><div><br></div></div>=
</div></blockquote><div><br></div><div>I don&#39;t really see the point in =
doing that. You&#39;re not providing better error messages, and you&#39;re =
not really providing better documentation of anything. `Meta::f` is perfect=
ly capable of having concept constraints written into it, and all `hooray` =
is doing is passing a value to that function. So why does `hooray` need to =
mimic the constraints of `Meta::f`?</div><br></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/6648df17-d00c-400f-a698-2b3ed968efdb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6648df17-d00c-400f-a698-2b3ed968efdb=
%40isocpp.org</a>.<br />

------=_Part_641_772313265.1533868342334--

------=_Part_640_62721180.1533868342334--

.


Author: Justin Bassett <jbassett271@gmail.com>
Date: Thu, 9 Aug 2018 20:25:36 -0700
Raw View
--000000000000a77e9305730c4c3a
Content-Type: text/plain; charset="UTF-8"

The main thing I was getting at was that there's this restriction of
concepts to be only at namespace-scope, but I haven't found an explanation
for that. It's an extra restriction, a special case. Declaring them at
class scope is useful in a variety of situations, not just for
metaprogramming techniques like what I was hinting at with my possible
use-case. It's inconsistent with the other template things in C++ as of
yet. In other words, I assume there must have been a compelling argument
for restricting them to namespace-scope, otherwise it just seems arbitrary
and limiting.


On Thu, Aug 9, 2018 at 7:32 PM Nicol Bolas <jmckesson@gmail.com> wrote:

>
>
> On Thursday, August 9, 2018 at 9:53:26 PM UTC-4, Arthur O'Dwyer wrote:
>>
>> On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote:
>>>
>>> I recently discovered that concepts must be defined at namespace scope.
>>> What is the reason for this? It seems like an arbitrary restriction to me,
>>> when alias templates and variable templates can appear at class scope.
>>>
>>> This realization came from thinking about passing concepts as template
>>> parameters. It currently is not possible. Template parameters can't be
>>> concepts; they can only be template template (type) parameters, type
>>> parameters, or value parameters. Wrapping the concept inside a struct
>>> doesn't work as well, since the concept must be defined at namespace scope.
>>>
>>
>>
>> Here's an example involving "member concept aliases" that I worked up the
>> other day on Slack:
>>
>> struct One {
>>     template<Red T> static void f(T);
>>     template<class T> using concept concept_ = Red<T>;
>> };
>> struct Two {
>>     template<Blue T> static void f(T);
>>     template<class T> using concept concept_ = Blue<T>;
>> };
>>
>> template<class Meta, class T> requires(Meta::template concept_<T>)
>> void hooray(T t) {
>>     return Meta::f(t);
>> }
>>
>> // ...
>> hooray<One>(a_red_thing);
>> hooray<Two>(a_blue_thing);
>>
>>
> I don't really see the point in doing that. You're not providing better
> error messages, and you're not really providing better documentation of
> anything. `Meta::f` is perfectly capable of having concept constraints
> written into it, and all `hooray` is doing is passing a value to that
> function. So why does `hooray` need to mimic the constraints of `Meta::f`?
>
> --
> 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/6648df17-d00c-400f-a698-2b3ed968efdb%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6648df17-d00c-400f-a698-2b3ed968efdb%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CAPuuy5doSbhw7HAdx8CiZKc5EjbbLDh2FcXnh0pEy0aE6wMajA%40mail.gmail.com.

--000000000000a77e9305730c4c3a
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">The main thing I was getting at was that there&#39;s this =
restriction of concepts to be only at namespace-scope, but I haven&#39;t fo=
und an explanation for that. It&#39;s an extra restriction, a special case.=
 Declaring them at class scope is useful in a variety of situations, not ju=
st for metaprogramming techniques like what I was hinting at with my possib=
le use-case. It&#39;s inconsistent with the other template things in C++ as=
 of yet. In other words, I assume there must have been a compelling argumen=
t for restricting them to namespace-scope, otherwise it just seems arbitrar=
y and limiting.<div><br></div></div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr">On Thu, Aug 9, 2018 at 7:32 PM Nicol Bolas &lt;<a href=3D"mailto:j=
mckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><br><br>On Thursday, August 9, 2018 at=
 9:53:26 PM UTC-4, Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr">On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7=
, Justin Bassett wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr">I recently discovered that concepts must be defined at namespace scope=
.. What is the reason for this? It seems like an arbitrary restriction to me=
, when alias templates and variable templates can appear at class scope.<di=
v><br></div><div>This realization came from thinking about passing concepts=
 as template parameters. It currently is not possible. Template parameters =
can&#39;t be concepts; they can only be template template (type) parameters=
, type parameters, or value parameters. Wrapping the concept inside a struc=
t doesn&#39;t work as well, since the concept must be defined at namespace =
scope.</div></div></blockquote><div><br></div><div><br></div><div>Here&#39;=
s an example involving &quot;member concept aliases&quot; that I worked up =
the other day on Slack:</div><div><br></div><div><div style=3D"background-c=
olor:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-wor=
d"><code><div><span style=3D"color:#008">struct</span><span style=3D"color:=
#000"> </span><span style=3D"color:#606">One</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#606">Red</span><span styl=
e=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">static</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">void</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">T</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">using</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">concept</span=
><span style=3D"color:#000"> concept_ </span><span style=3D"color:#660">=3D=
</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Red</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</spa=
n><span style=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">struct</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#606">Two</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:#008">template</span><span style=3D"colo=
r:#660">&lt;</span><span style=3D"color:#606">Blue</span><span style=3D"col=
or:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">static</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">void</span><span style=3D"color:=
#000"> f</span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">T</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span st=
yle=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">using</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#008">concept</span><span sty=
le=3D"color:#000"> concept_ </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Blue</span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span s=
tyle=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br></span><span=
 style=3D"color:#660">};</span><span style=3D"color:#000"><br><br></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#008">class</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#606">Meta</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">class</span><=
span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><s=
pan style=3D"color:#000"> requires</span><span style=3D"color:#660">(</span=
><span style=3D"color:#606">Meta</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#008">template</span><span style=3D"color:#000"> conce=
pt_</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">=
T</span><span style=3D"color:#660">&gt;)</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#008">void</span><span style=3D"color:#000">=
 hooray</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>T t</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#606">Meta</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#000">f</span><span style=3D"color:#6=
60">(</span><span style=3D"color:#000">t</span><span style=3D"color:#660">)=
;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}<=
/span><span style=3D"color:#000"><br><br></span><span style=3D"color:#800">=
// ...</span><span style=3D"color:#000"><br>hooray</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#606">One</span><span style=3D"col=
or:#660">&gt;(</span><span style=3D"color:#000">a_red_thing</span><span sty=
le=3D"color:#660">);</span><span style=3D"color:#000"><br>hooray</span><spa=
n style=3D"color:#660">&lt;</span><span style=3D"color:#606">Two</span><spa=
n style=3D"color:#660">&gt;(</span><span style=3D"color:#000">a_blue_thing<=
/span><span style=3D"color:#660">);</span></div></code></div><div><br></div=
></div></div></blockquote><div><br></div><div>I don&#39;t really see the po=
int in doing that. You&#39;re not providing better error messages, and you&=
#39;re not really providing better documentation of anything. `Meta::f` is =
perfectly capable of having concept constraints written into it, and all `h=
ooray` is doing is passing a value to that function. So why does `hooray` n=
eed to mimic the constraints of `Meta::f`?</div><br></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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/6648df17-d00c-400f-a698-2b3ed968efdb%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6648df17-d00c-=
400f-a698-2b3ed968efdb%40isocpp.org</a>.<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/CAPuuy5doSbhw7HAdx8CiZKc5EjbbLDh2FcXn=
h0pEy0aE6wMajA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5doSbhw7HAd=
x8CiZKc5EjbbLDh2FcXnh0pEy0aE6wMajA%40mail.gmail.com</a>.<br />

--000000000000a77e9305730c4c3a--

.


Author: Justin Bassett <jbassett271@gmail.com>
Date: Thu, 9 Aug 2018 20:33:23 -0700
Raw View
--00000000000087aa3e05730c686f
Content-Type: text/plain; charset="UTF-8"

>
> Casey Carter pointed out that *almost* the same effect can be achieved via
>
> struct One {
>     template<Red T> static void f(T);
> };
> struct Two {
>     template<Blue T> static void f(T);
> };
>
> template<class Meta, class T> requires requires (T t) { Meta::f(t); }
> void hooray(T t) {
>     return Meta::f(t);
> }
>
> // ...
> hooray<One>(a_red_thing);
> hooray<Two>(a_blue_thing);
>
>
The problem with this solution (and the one with variable templates) is
that you lose the nice error messages. With a direct concept, the compilers
give error messages that explain why the type doesn't mean the concept.
With these alternatives, the compilers just say, "It doesn't work because
Meta::f(t) wasn't valid" or "It doesn't work because concept_ was false".
One could argue that it's a QOI issue, but I disagree, because we discarded
the information that we considered it an explicit concept.

--
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/CAPuuy5c7Rz3W1D7kgL4kiBzvPVF1JvJG9OPacqXE1FDNObydzA%40mail.gmail.com.

--00000000000087aa3e05730c686f
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div><div>Casey Carter pointed out that <i>almost</i> the =
same effect can be achieved via<br></div></div><div><br></div><div><div cla=
ss=3D"m_5209086135324966804prettyprint" style=3D"background-color:rgb(250,2=
50,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code class=
=3D"m_5209086135324966804prettyprint"><div class=3D"m_5209086135324966804su=
bprettyprint"><span style=3D"color:#008" class=3D"m_5209086135324966804styl=
ed-by-prettify">struct</span><span style=3D"color:#000" class=3D"m_52090861=
35324966804styled-by-prettify"> </span><span style=3D"color:#606" class=3D"=
m_5209086135324966804styled-by-prettify">One</span><span style=3D"color:#00=
0" class=3D"m_5209086135324966804styled-by-prettify"> </span><span style=3D=
"color:#660" class=3D"m_5209086135324966804styled-by-prettify">{</span><spa=
n style=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_52090861353249=
66804styled-by-prettify">template</span><span style=3D"color:#660" class=3D=
"m_5209086135324966804styled-by-prettify">&lt;</span><span style=3D"color:#=
606" class=3D"m_5209086135324966804styled-by-prettify">Red</span><span styl=
e=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify"> T</span=
><span style=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettif=
y">&gt;</span><span style=3D"color:#000" class=3D"m_5209086135324966804styl=
ed-by-prettify"> </span><span style=3D"color:#008" class=3D"m_5209086135324=
966804styled-by-prettify">static</span><span style=3D"color:#000" class=3D"=
m_5209086135324966804styled-by-prettify"> </span><span style=3D"color:#008"=
 class=3D"m_5209086135324966804styled-by-prettify">void</span><span style=
=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify"> f</span>=
<span style=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettify=
">(</span><span style=3D"color:#000" class=3D"m_5209086135324966804styled-b=
y-prettify">T</span><span style=3D"color:#660" class=3D"m_52090861353249668=
04styled-by-prettify">);</span><span style=3D"color:#000" class=3D"m_520908=
6135324966804styled-by-prettify"><br></span><span style=3D"color:#660" clas=
s=3D"m_5209086135324966804styled-by-prettify">};</span><span style=3D"color=
:#000" class=3D"m_5209086135324966804styled-by-prettify"><br></span><span s=
tyle=3D"color:#008" class=3D"m_5209086135324966804styled-by-prettify">struc=
t</span><span style=3D"color:#000" class=3D"m_5209086135324966804styled-by-=
prettify"> </span><span style=3D"color:#606" class=3D"m_5209086135324966804=
styled-by-prettify">Two</span><span style=3D"color:#000" class=3D"m_5209086=
135324966804styled-by-prettify"> </span><span style=3D"color:#660" class=3D=
"m_5209086135324966804styled-by-prettify">{</span><span style=3D"color:#000=
" class=3D"m_5209086135324966804styled-by-prettify"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:#008" class=3D"m_5209086135324966804styled-by-pretti=
fy">template</span><span style=3D"color:#660" class=3D"m_520908613532496680=
4styled-by-prettify">&lt;</span><span style=3D"color:#606" class=3D"m_52090=
86135324966804styled-by-prettify">Blue</span><span style=3D"color:#000" cla=
ss=3D"m_5209086135324966804styled-by-prettify"> T</span><span style=3D"colo=
r:#660" class=3D"m_5209086135324966804styled-by-prettify">&gt;</span><span =
style=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify"> </s=
pan><span style=3D"color:#008" class=3D"m_5209086135324966804styled-by-pret=
tify">static</span><span style=3D"color:#000" class=3D"m_520908613532496680=
4styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_52090861=
35324966804styled-by-prettify">void</span><span style=3D"color:#000" class=
=3D"m_5209086135324966804styled-by-prettify"> f</span><span style=3D"color:=
#660" class=3D"m_5209086135324966804styled-by-prettify">(</span><span style=
=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify">T</span><=
span style=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettify"=
>);</span><span style=3D"color:#000" class=3D"m_5209086135324966804styled-b=
y-prettify"><br></span><span style=3D"color:#660" class=3D"m_52090861353249=
66804styled-by-prettify">};</span><span style=3D"color:#000" class=3D"m_520=
9086135324966804styled-by-prettify"><br><br></span><span style=3D"color:#00=
8" class=3D"m_5209086135324966804styled-by-prettify">template</span><span s=
tyle=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettify">&lt;<=
/span><span style=3D"color:#008" class=3D"m_5209086135324966804styled-by-pr=
ettify">class</span><span style=3D"color:#000" class=3D"m_52090861353249668=
04styled-by-prettify"> </span><span style=3D"color:#606" class=3D"m_5209086=
135324966804styled-by-prettify">Meta</span><span style=3D"color:#660" class=
=3D"m_5209086135324966804styled-by-prettify">,</span><span style=3D"color:#=
000" class=3D"m_5209086135324966804styled-by-prettify"> </span><span style=
=3D"color:#008" class=3D"m_5209086135324966804styled-by-prettify">class</sp=
an><span style=3D"color:#000" class=3D"m_5209086135324966804styled-by-prett=
ify"> T</span><span style=3D"color:#660" class=3D"m_5209086135324966804styl=
ed-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_5209086135=
324966804styled-by-prettify"> requires requires </span><span style=3D"color=
:#660" class=3D"m_5209086135324966804styled-by-prettify">(</span><span styl=
e=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify">T t</spa=
n><span style=3D"color:#660" class=3D"m_5209086135324966804styled-by-pretti=
fy">)</span><span style=3D"color:#000" class=3D"m_5209086135324966804styled=
-by-prettify"> </span><span style=3D"color:#660" class=3D"m_520908613532496=
6804styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_52090=
86135324966804styled-by-prettify"> </span><span style=3D"color:#606" class=
=3D"m_5209086135324966804styled-by-prettify">Meta</span><span style=3D"colo=
r:#660" class=3D"m_5209086135324966804styled-by-prettify">::</span><span st=
yle=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify">f</spa=
n><span style=3D"color:#660" class=3D"m_5209086135324966804styled-by-pretti=
fy">(</span><span style=3D"color:#000" class=3D"m_5209086135324966804styled=
-by-prettify">t</span><span style=3D"color:#660" class=3D"m_520908613532496=
6804styled-by-prettify">);</span><span style=3D"color:#000" class=3D"m_5209=
086135324966804styled-by-prettify"> </span><span style=3D"color:#660" class=
=3D"m_5209086135324966804styled-by-prettify">}</span><span style=3D"color:#=
000" class=3D"m_5209086135324966804styled-by-prettify"><br></span><span sty=
le=3D"color:#008" class=3D"m_5209086135324966804styled-by-prettify">void</s=
pan><span style=3D"color:#000" class=3D"m_5209086135324966804styled-by-pret=
tify"> hooray</span><span style=3D"color:#660" class=3D"m_52090861353249668=
04styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_5209086=
135324966804styled-by-prettify">T t</span><span style=3D"color:#660" class=
=3D"m_5209086135324966804styled-by-prettify">)</span><span style=3D"color:#=
000" class=3D"m_5209086135324966804styled-by-prettify"> </span><span style=
=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettify">{</span><=
span style=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_52090861353=
24966804styled-by-prettify">return</span><span style=3D"color:#000" class=
=3D"m_5209086135324966804styled-by-prettify"> </span><span style=3D"color:#=
606" class=3D"m_5209086135324966804styled-by-prettify">Meta</span><span sty=
le=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettify">::</spa=
n><span style=3D"color:#000" class=3D"m_5209086135324966804styled-by-pretti=
fy">f</span><span style=3D"color:#660" class=3D"m_5209086135324966804styled=
-by-prettify">(</span><span style=3D"color:#000" class=3D"m_520908613532496=
6804styled-by-prettify">t</span><span style=3D"color:#660" class=3D"m_52090=
86135324966804styled-by-prettify">);</span><span style=3D"color:#000" class=
=3D"m_5209086135324966804styled-by-prettify"><br></span><span style=3D"colo=
r:#660" class=3D"m_5209086135324966804styled-by-prettify">}</span><span sty=
le=3D"color:#000" class=3D"m_5209086135324966804styled-by-prettify"><br><br=
></span><span style=3D"color:#800" class=3D"m_5209086135324966804styled-by-=
prettify">// ...</span><span style=3D"color:#000" class=3D"m_52090861353249=
66804styled-by-prettify"><br>hooray</span><span style=3D"color:#660" class=
=3D"m_5209086135324966804styled-by-prettify">&lt;</span><span style=3D"colo=
r:#606" class=3D"m_5209086135324966804styled-by-prettify">One</span><span s=
tyle=3D"color:#660" class=3D"m_5209086135324966804styled-by-prettify">&gt;(=
</span><span style=3D"color:#000" class=3D"m_5209086135324966804styled-by-p=
rettify">a_red_thing</span><span style=3D"color:#660" class=3D"m_5209086135=
324966804styled-by-prettify">);</span><span style=3D"color:#000" class=3D"m=
_5209086135324966804styled-by-prettify"><br>hooray</span><span style=3D"col=
or:#660" class=3D"m_5209086135324966804styled-by-prettify">&lt;</span><span=
 style=3D"color:#606" class=3D"m_5209086135324966804styled-by-prettify">Two=
</span><span style=3D"color:#660" class=3D"m_5209086135324966804styled-by-p=
rettify">&gt;(</span><span style=3D"color:#000" class=3D"m_5209086135324966=
804styled-by-prettify">a_blue_thing</span><span style=3D"color:#660" class=
=3D"m_5209086135324966804styled-by-prettify">);</span></div></code></div><d=
iv><br></div></div></div></blockquote><div><br></div><div>The problem with =
this solution (and the one with variable templates) is that you lose the ni=
ce error messages. With a direct <font face=3D"monospace, monospace">concep=
t</font>, the compilers give error messages that explain why the type doesn=
&#39;t mean the concept. With these alternatives, the compilers just say, &=
quot;It doesn&#39;t work because <font face=3D"monospace, monospace">Meta::=
f(t)</font> wasn&#39;t valid&quot; or &quot;It doesn&#39;t work because <fo=
nt face=3D"monospace, monospace">concept_</font> was false&quot;. One could=
 argue that it&#39;s a QOI issue, but I disagree, because we discarded the =
information that we considered it an explicit concept.</div><div><br></div>=
</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/CAPuuy5c7Rz3W1D7kgL4kiBzvPVF1JvJG9OPa=
cqXE1FDNObydzA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5c7Rz3W1D7k=
gL4kiBzvPVF1JvJG9OPacqXE1FDNObydzA%40mail.gmail.com</a>.<br />

--00000000000087aa3e05730c686f--

.


Author: Justin Bassett <jbassett271@gmail.com>
Date: Thu, 9 Aug 2018 20:41:36 -0700
Raw View
--000000000000dd03e905730c8534
Content-Type: text/plain; charset="UTF-8"

Let me put it this way: I haven't found very good use-cases for concepts
inside classes as of yet.  IMO, it is more consistent and logical, but
that's not a use-case. However, I do believe that allowing concepts at
class scope will encourage exploration, which I believe has potential to
come up with useful techniques which we have not yet thought of.

I do have some partial ideas, though. Aside from having the concept
declared closer to the point of use, I had a thought that maybe with
reflection, perhaps requiring something like metaclasses, one could
implement something like C++0x concepts as a library, where an interface
describing all the required functions is passed in, and a concept with some
other information is passed out. However, in my thoughts surrounding this,
it's either necessary or extremely helpful for concepts to be allowed at
class scope.

On Thu, Aug 9, 2018 at 8:33 PM Justin Bassett <jbassett271@gmail.com> wrote:

> Casey Carter pointed out that *almost* the same effect can be achieved via
>>
>> struct One {
>>     template<Red T> static void f(T);
>> };
>> struct Two {
>>     template<Blue T> static void f(T);
>> };
>>
>> template<class Meta, class T> requires requires (T t) { Meta::f(t); }
>> void hooray(T t) {
>>     return Meta::f(t);
>> }
>>
>> // ...
>> hooray<One>(a_red_thing);
>> hooray<Two>(a_blue_thing);
>>
>>
> The problem with this solution (and the one with variable templates) is
> that you lose the nice error messages. With a direct concept, the
> compilers give error messages that explain why the type doesn't mean the
> concept. With these alternatives, the compilers just say, "It doesn't work
> because Meta::f(t) wasn't valid" or "It doesn't work because concept_ was
> false". One could argue that it's a QOI issue, but I disagree, because we
> discarded the information that we considered it an explicit concept.
>
>

--
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/CAPuuy5fc3eOuWpEb60OP5UYf-fuT22eyBBKG2SMbt%2B-SijJ49g%40mail.gmail.com.

--000000000000dd03e905730c8534
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Let me put it this way: I haven&#39;t found very good use-=
cases for concepts inside classes as of yet.=C2=A0

IMO,=C2=A0it is more consistent and logical, but that&#39;s not a use-case.=
 However, I do believe that allowing concepts at class scope will encourage=
 exploration, which I believe has potential to come up with useful techniqu=
es which we have not yet thought of.<div><br></div><div>I do have some part=
ial ideas, though. Aside from having the concept declared closer to the poi=
nt of use, I had a thought that maybe with reflection, perhaps requiring so=
mething like metaclasses, one could implement something like C++0x concepts=
 as a library, where an interface describing all the required functions is =
passed in, and a concept with some other information is passed out. However=
, in my thoughts surrounding this, it&#39;s either necessary or extremely h=
elpful for concepts to be allowed at class scope.</div></div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr">On Thu, Aug 9, 2018 at 8:33 PM Justin Bas=
sett &lt;<a href=3D"mailto:jbassett271@gmail.com">jbassett271@gmail.com</a>=
&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div c=
lass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><=
div>Casey Carter pointed out that <i>almost</i> the same effect can be achi=
eved via<br></div></div><div><br></div><div><div class=3D"m_-48434438881078=
9425m_5209086135324966804prettyprint" style=3D"background-color:rgb(250,250=
,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code class=
=3D"m_-484344388810789425m_5209086135324966804prettyprint"><div class=3D"m_=
-484344388810789425m_5209086135324966804subprettyprint"><span style=3D"colo=
r:#008" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pretti=
fy">struct</span><span style=3D"color:#000" class=3D"m_-484344388810789425m=
_5209086135324966804styled-by-prettify"> </span><span style=3D"color:#606" =
class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">One<=
/span><span style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135=
324966804styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_=
-484344388810789425m_5209086135324966804styled-by-prettify">{</span><span s=
tyle=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=
=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">template<=
/span><span style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135=
324966804styled-by-prettify">&lt;</span><span style=3D"color:#606" class=3D=
"m_-484344388810789425m_5209086135324966804styled-by-prettify">Red</span><s=
pan style=3D"color:#000" class=3D"m_-484344388810789425m_520908613532496680=
4styled-by-prettify"> T</span><span style=3D"color:#660" class=3D"m_-484344=
388810789425m_5209086135324966804styled-by-prettify">&gt;</span><span style=
=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-b=
y-prettify"> </span><span style=3D"color:#008" class=3D"m_-4843443888107894=
25m_5209086135324966804styled-by-prettify">static</span><span style=3D"colo=
r:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pretti=
fy"> </span><span style=3D"color:#008" class=3D"m_-484344388810789425m_5209=
086135324966804styled-by-prettify">void</span><span style=3D"color:#000" cl=
ass=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify"> f</sp=
an><span style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324=
966804styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-48=
4344388810789425m_5209086135324966804styled-by-prettify">T</span><span styl=
e=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966804styled-=
by-prettify">);</span><span style=3D"color:#000" class=3D"m_-48434438881078=
9425m_5209086135324966804styled-by-prettify"><br></span><span style=3D"colo=
r:#660" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pretti=
fy">};</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_520=
9086135324966804styled-by-prettify"><br></span><span style=3D"color:#008" c=
lass=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">struc=
t</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_52090861=
35324966804styled-by-prettify"> </span><span style=3D"color:#606" class=3D"=
m_-484344388810789425m_5209086135324966804styled-by-prettify">Two</span><sp=
an style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804=
styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-48434438=
8810789425m_5209086135324966804styled-by-prettify">{</span><span style=3D"c=
olor:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_-4843=
44388810789425m_5209086135324966804styled-by-prettify">template</span><span=
 style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966804st=
yled-by-prettify">&lt;</span><span style=3D"color:#606" class=3D"m_-4843443=
88810789425m_5209086135324966804styled-by-prettify">Blue</span><span style=
=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-b=
y-prettify"> T</span><span style=3D"color:#660" class=3D"m_-484344388810789=
425m_5209086135324966804styled-by-prettify">&gt;</span><span style=3D"color=
:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettif=
y"> </span><span style=3D"color:#008" class=3D"m_-484344388810789425m_52090=
86135324966804styled-by-prettify">static</span><span style=3D"color:#000" c=
lass=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify"> </sp=
an><span style=3D"color:#008" class=3D"m_-484344388810789425m_5209086135324=
966804styled-by-prettify">void</span><span style=3D"color:#000" class=3D"m_=
-484344388810789425m_5209086135324966804styled-by-prettify"> f</span><span =
style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966804sty=
led-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-48434438881=
0789425m_5209086135324966804styled-by-prettify">T</span><span style=3D"colo=
r:#660" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pretti=
fy">);</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_520=
9086135324966804styled-by-prettify"><br></span><span style=3D"color:#660" c=
lass=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">};</s=
pan><span style=3D"color:#000" class=3D"m_-484344388810789425m_520908613532=
4966804styled-by-prettify"><br><br></span><span style=3D"color:#008" class=
=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">template<=
/span><span style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135=
324966804styled-by-prettify">&lt;</span><span style=3D"color:#008" class=3D=
"m_-484344388810789425m_5209086135324966804styled-by-prettify">class</span>=
<span style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966=
804styled-by-prettify"> </span><span style=3D"color:#606" class=3D"m_-48434=
4388810789425m_5209086135324966804styled-by-prettify">Meta</span><span styl=
e=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966804styled-=
by-prettify">,</span><span style=3D"color:#000" class=3D"m_-484344388810789=
425m_5209086135324966804styled-by-prettify"> </span><span style=3D"color:#0=
08" class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">=
class</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_5209=
086135324966804styled-by-prettify"> T</span><span style=3D"color:#660" clas=
s=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">&gt;</sp=
an><span style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324=
966804styled-by-prettify"> requires requires </span><span style=3D"color:#6=
60" class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">=
(</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_52090861=
35324966804styled-by-prettify">T t</span><span style=3D"color:#660" class=
=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">)</span><=
span style=3D"color:#000" class=3D"m_-484344388810789425m_52090861353249668=
04styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_-484344=
388810789425m_5209086135324966804styled-by-prettify">{</span><span style=3D=
"color:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-by-p=
rettify"> </span><span style=3D"color:#606" class=3D"m_-484344388810789425m=
_5209086135324966804styled-by-prettify">Meta</span><span style=3D"color:#66=
0" class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">:=
:</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_52090861=
35324966804styled-by-prettify">f</span><span style=3D"color:#660" class=3D"=
m_-484344388810789425m_5209086135324966804styled-by-prettify">(</span><span=
 style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804st=
yled-by-prettify">t</span><span style=3D"color:#660" class=3D"m_-4843443888=
10789425m_5209086135324966804styled-by-prettify">);</span><span style=3D"co=
lor:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pret=
tify"> </span><span style=3D"color:#660" class=3D"m_-484344388810789425m_52=
09086135324966804styled-by-prettify">}</span><span style=3D"color:#000" cla=
ss=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify"><br></s=
pan><span style=3D"color:#008" class=3D"m_-484344388810789425m_520908613532=
4966804styled-by-prettify">void</span><span style=3D"color:#000" class=3D"m=
_-484344388810789425m_5209086135324966804styled-by-prettify"> hooray</span>=
<span style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966=
804styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-48434=
4388810789425m_5209086135324966804styled-by-prettify">T t</span><span style=
=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966804styled-b=
y-prettify">)</span><span style=3D"color:#000" class=3D"m_-4843443888107894=
25m_5209086135324966804styled-by-prettify"> </span><span style=3D"color:#66=
0" class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">{=
</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_520908613=
5324966804styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color=
:#008" class=3D"m_-484344388810789425m_5209086135324966804styled-by-prettif=
y">return</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_=
5209086135324966804styled-by-prettify"> </span><span style=3D"color:#606" c=
lass=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">Meta<=
/span><span style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135=
324966804styled-by-prettify">::</span><span style=3D"color:#000" class=3D"m=
_-484344388810789425m_5209086135324966804styled-by-prettify">f</span><span =
style=3D"color:#660" class=3D"m_-484344388810789425m_5209086135324966804sty=
led-by-prettify">(</span><span style=3D"color:#000" class=3D"m_-48434438881=
0789425m_5209086135324966804styled-by-prettify">t</span><span style=3D"colo=
r:#660" class=3D"m_-484344388810789425m_5209086135324966804styled-by-pretti=
fy">);</span><span style=3D"color:#000" class=3D"m_-484344388810789425m_520=
9086135324966804styled-by-prettify"><br></span><span style=3D"color:#660" c=
lass=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">}</sp=
an><span style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324=
966804styled-by-prettify"><br><br></span><span style=3D"color:#800" class=
=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">// ...</s=
pan><span style=3D"color:#000" class=3D"m_-484344388810789425m_520908613532=
4966804styled-by-prettify"><br>hooray</span><span style=3D"color:#660" clas=
s=3D"m_-484344388810789425m_5209086135324966804styled-by-prettify">&lt;</sp=
an><span style=3D"color:#606" class=3D"m_-484344388810789425m_5209086135324=
966804styled-by-prettify">One</span><span style=3D"color:#660" class=3D"m_-=
484344388810789425m_5209086135324966804styled-by-prettify">&gt;(</span><spa=
n style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804s=
tyled-by-prettify">a_red_thing</span><span style=3D"color:#660" class=3D"m_=
-484344388810789425m_5209086135324966804styled-by-prettify">);</span><span =
style=3D"color:#000" class=3D"m_-484344388810789425m_5209086135324966804sty=
led-by-prettify"><br>hooray</span><span style=3D"color:#660" class=3D"m_-48=
4344388810789425m_5209086135324966804styled-by-prettify">&lt;</span><span s=
tyle=3D"color:#606" class=3D"m_-484344388810789425m_5209086135324966804styl=
ed-by-prettify">Two</span><span style=3D"color:#660" class=3D"m_-4843443888=
10789425m_5209086135324966804styled-by-prettify">&gt;(</span><span style=3D=
"color:#000" class=3D"m_-484344388810789425m_5209086135324966804styled-by-p=
rettify">a_blue_thing</span><span style=3D"color:#660" class=3D"m_-48434438=
8810789425m_5209086135324966804styled-by-prettify">);</span></div></code></=
div><div><br></div></div></div></blockquote><div><br></div><div>The problem=
 with this solution (and the one with variable templates) is that you lose =
the nice error messages. With a direct <font face=3D"monospace, monospace">=
concept</font>, the compilers give error messages that explain why the type=
 doesn&#39;t mean the concept. With these alternatives, the compilers just =
say, &quot;It doesn&#39;t work because <font face=3D"monospace, monospace">=
Meta::f(t)</font> wasn&#39;t valid&quot; or &quot;It doesn&#39;t work becau=
se <font face=3D"monospace, monospace">concept_</font> was false&quot;. One=
 could argue that it&#39;s a QOI issue, but I disagree, because we discarde=
d the information that we considered it an explicit concept.</div><div><br>=
</div></div></div>
</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/CAPuuy5fc3eOuWpEb60OP5UYf-fuT22eyBBKG=
2SMbt%2B-SijJ49g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5fc3eOuWp=
Eb60OP5UYf-fuT22eyBBKG2SMbt%2B-SijJ49g%40mail.gmail.com</a>.<br />

--000000000000dd03e905730c8534--

.


Author: inkwizytoryankes@gmail.com
Date: Fri, 10 Aug 2018 00:24:57 -0700 (PDT)
Raw View
------=_Part_638_172201033.1533885897630
Content-Type: multipart/alternative;
 boundary="----=_Part_639_388732386.1533885897631"

------=_Part_639_388732386.1533885897631
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, August 10, 2018 at 3:53:26 AM UTC+2, Arthur O'Dwyer wrote:
>
> On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote:
>>
>> I recently discovered that concepts must be defined at namespace scope.=
=20
>> What is the reason for this? It seems like an arbitrary restriction to m=
e,=20
>> when alias templates and variable templates can appear at class scope.
>>
>> This realization came from thinking about passing concepts as template=
=20
>> parameters. It currently is not possible. Template parameters can't be=
=20
>> concepts; they can only be template template (type) parameters, type=20
>> parameters, or value parameters. Wrapping the concept inside a struct=20
>> doesn't work as well, since the concept must be defined at namespace sco=
pe.
>>
>
>
> Here's an example involving "member concept aliases" that I worked up the=
=20
> other day on Slack:
>
> struct One {
>     template<Red T> static void f(T);
>     template<class T> using concept concept_ =3D Red<T>;
> };
> struct Two {
>     template<Blue T> static void f(T);
>     template<class T> using concept concept_ =3D Blue<T>;
> };
>
> template<class Meta, class T> requires(Meta::template concept_<T>)
> void hooray(T t) {
>     return Meta::f(t);
> }
>
> // ...
> hooray<One>(a_red_thing);
> hooray<Two>(a_blue_thing);
>
> (It occurred to me that it is very convenient how neither `type` nor=20
> `value` is a reserved word in C++; and that it is corresponding unfortuna=
te=20
> that `concept` *will* be a keyword. Notice the use of `concept_` above.)
>
> Casey Carter pointed out that *almost* the same effect can be achieved vi=
a
>
> struct One {
>     template<Red T> static void f(T);
> };
> struct Two {
>     template<Blue T> static void f(T);
> };
>
> template<class Meta, class T> requires requires (T t) { Meta::f(t); }
> void hooray(T t) {
>     return Meta::f(t);
> }
>
> // ...
> hooray<One>(a_red_thing);
> hooray<Two>(a_blue_thing);
>
> The difference between the "concept" approach and the "anonymous=20
> requires-clause" approach has to do with subsumption rules.
> Also, this smells a lot like smuggling a concept (e.g. `Red`) through a=
=20
> function declaration (`One::f`), i.e., a sneaky technical workaround for =
a=20
> missing feature in the language, analogous to how we used to have to=20
> smuggle variable templates through class templates (e.g. every type-trait=
=20
> ever).
>
> If you're willing to forgo subsumption (which I personally am, AFAIK),=20
> then you can already achieve the goal of "member concepts" by simply=20
> rewriting all your concepts as plain old variable templates. To the exten=
t=20
> that this doesn't work, it shows why we might want to add real member=20
> concepts and concept aliases. To the extent that this does work, it shows=
=20
> why we don't technically need the `concept` keyword at all.
>
> struct One {
>     template<Red T> static void f(T);
>     template<class T> static constexpr bool concept_ =3D Red<T>;
> };
> struct Two {
>     template<Blue T> static void f(T);
>     template<class T> static constexpr bool concept_ =3D Blue<T>;
> };
>
> template<class Meta, class T> requires Meta::template concept_<T>
> void hooray(T t) {
>     return Meta::f(t);
> }
>
> // ...
> hooray<One>(a_red_thing);
> hooray<Two>(a_blue_thing);
>
> Here's the example, complete and compilable.=20
> <https://wandbox.org/permlink/ySWp3QWnqWIxylQN>
>
> =E2=80=93Arthur
>

Probably one thing that prevent this usage is that `concept_` concept isn't=
=20
concept at least when `hooray` is parsed, you will need use prefix=20
`concept` to allow correct parsing of this code (same as you need use=20
`template` or `typename`).

Another thing, why not use `some_concept<M, T>`?

Overall I think this was deliberately done to simplify whole design and=20
avion any unexpected iterations, It would be bad if concepts skyrocket to=
=20
level of template metaprograming from beginning, AFAIK right now you can't=
=20
do any arbitrary ordering of concepts that depends on metaprograming and=20
this is good thing.

--=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/0b82cc47-9dd1-41f1-80b4-3e1469aaa9a9%40isocpp.or=
g.

------=_Part_639_388732386.1533885897631
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, August 10, 2018 at 3:53:26 AM UTC+2, Ar=
thur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr">On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I recently =
discovered that concepts must be defined at namespace scope. What is the re=
ason for this? It seems like an arbitrary restriction to me, when alias tem=
plates and variable templates can appear at class scope.<div><br></div><div=
>This realization came from thinking about passing concepts as template par=
ameters. It currently is not possible. Template parameters can&#39;t be con=
cepts; they can only be template template (type) parameters, type parameter=
s, or value parameters. Wrapping the concept inside a struct doesn&#39;t wo=
rk as well, since the concept must be defined at namespace scope.</div></di=
v></blockquote><div><br></div><div><br></div><div>Here&#39;s an example inv=
olving &quot;member concept aliases&quot; that I worked up the other day on=
 Slack:</div><div><br></div><div><div style=3D"background-color:rgb(250,250=
,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><s=
pan style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#606">One</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">template</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#606">Red</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">static</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">void</span><span style=3D"color:#000"> f=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">T</spa=
n><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0=
 =C2=A0 </span><span style=3D"color:#008">template</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"c=
olor:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">using</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">concept</span><span style=3D"co=
lor:#000"> concept_ </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Red</span><span style=3D=
"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"c=
olor:#660">&gt;;</span><span style=3D"color:#000"><br></span><span style=3D=
"color:#660">};</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#008">struct</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">Two</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#606">Blue</span><span style=3D"color:#000"> T</span><s=
pan style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">static</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">void</span><span style=3D"color:#000"> f</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">T</span><span styl=
e=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt=
;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">concept</span><span style=3D"color:#000"> c=
oncept_ </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Blue</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">=
&gt;;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">};</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#=
008">template</span><span style=3D"color:#660">&lt;</span><span style=3D"co=
lor:#008">class</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#606">Meta</span><span style=3D"color:#660">,</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">class</span><span style=3D"color:=
#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#=
000"> requires</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#606">Meta</span><span style=3D"color:#660">::</span><span style=3D"color=
:#008">template</span><span style=3D"color:#000"> concept_</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">&gt;)</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">void</span><span style=3D"color:#000"> hooray</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">T t</span><span st=
yle=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008">return</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Meta</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">f</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">t</span><span style=3D"color:#660">);</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#800">// ...</span><spa=
n style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#606">One</span><span style=3D"color:#660">&gt;(</s=
pan><span style=3D"color:#000">a_red_thing</span><span style=3D"color:#660"=
>);</span><span style=3D"color:#000"><br>hooray</span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#606">Two</span><span style=3D"color:=
#660">&gt;(</span><span style=3D"color:#000">a_blue_thing</span><span style=
=3D"color:#660">);</span></div></code></div><div><br></div></div><div>(It o=
ccurred to me that it is very convenient how neither `type` nor `value` is =
a reserved word in C++; and that it is corresponding unfortunate that `conc=
ept` <i>will</i> be a keyword. Notice the use of `concept_` above.)</div><d=
iv><br></div><div>Casey Carter pointed out that <i>almost</i> the same effe=
ct can be achieved via</div><div><br></div><div><div style=3D"background-co=
lor:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word=
"><code><div><span style=3D"color:#008">struct</span><span style=3D"color:#=
000"> </span><span style=3D"color:#606">One</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#606">Red</span><span style=
=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">static</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">void</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">T</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#008">struct</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#606">Two</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#606">Blue</span><span=
 style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">static</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">void</span><span st=
yle=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">T</span><span style=3D"color:#660">);</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"c=
olor:#000"><br><br></span><span style=3D"color:#008">template</span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> requires requires </=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">T t</spa=
n><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#606">Meta</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">f</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">t</span><span style=3D"color:#660">);</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">}</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#008">void</span><span style=3D"color:#=
000"> hooray</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">T t</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">f</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">t</span><span style=3D"color=
:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#660">}</span><span style=3D"color:#000"><br><br></span><span style=3D"colo=
r:#800">// ...</span><span style=3D"color:#000"><br>hooray</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#606">One</span><span styl=
e=3D"color:#660">&gt;(</span><span style=3D"color:#000">a_red_thing</span><=
span style=3D"color:#660">);</span><span style=3D"color:#000"><br>hooray</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Two</s=
pan><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">a_blu=
e_thing</span><span style=3D"color:#660">);</span></div></code></div><div><=
br></div></div><div>The difference between the &quot;concept&quot; approach=
 and the &quot;anonymous requires-clause&quot; approach has to do with subs=
umption rules.</div><div>Also, this smells a lot like smuggling a concept (=
e.g. `Red`) through a function declaration (`One::f`), i.e., a sneaky techn=
ical workaround for a missing feature in the language, analogous to how we =
used to have to smuggle variable templates through class templates (e.g. ev=
ery type-trait ever).</div><div><br></div><div>If you&#39;re willing to for=
go subsumption (which I personally am, AFAIK), then you can already achieve=
 the goal of &quot;member concepts&quot; by simply rewriting all your conce=
pts as plain old variable templates. To the extent that this doesn&#39;t wo=
rk, it shows why we might want to add real member concepts and concept alia=
ses. To the extent that this does work, it shows why we don&#39;t technical=
ly need the `concept` keyword at all.</div><div><br></div><div><div style=
=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187);wor=
d-wrap:break-word"><code><div><span style=3D"color:#008">struct</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#606">One</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Re=
d</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">static=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">void</=
span><span style=3D"color:#000"> f</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">T</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008"=
>template</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#008">class</span><span style=3D"color:#000"> T</span><span style=3D"color:=
#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">static</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">constexpr</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">bool</span><span style=3D"color:#000"> concept_ </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#606">Red</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#000">T</span><span style=3D"color:#660">&gt;;</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#008">struct</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Two</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Blue</span=
><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">static</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">void</span><s=
pan style=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">T</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">c=
lass</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&=
gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">sta=
tic</span><span style=3D"color:#000"> </span><span style=3D"color:#008">con=
stexpr</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
bool</span><span style=3D"color:#000"> concept_ </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
06">Blue</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#=
000">T</span><span style=3D"color:#660">&gt;;</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#660">};</span><span style=3D"color:#00=
0"><br><br></span><span style=3D"color:#008">template</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">class</span><span style=3D"color:#000"> T</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"> requires </span><span sty=
le=3D"color:#606">Meta</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#008">template</span><span style=3D"color:#000"> concept_</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><s=
pan style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">void</span><span style=3D"color:#000"> hooray</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">T t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">return</span><span style=3D"color:#000"> =
</span><span style=3D"color:#606">Meta</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">f</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">t</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span=
 style=3D"color:#000"><br><br></span><span style=3D"color:#800">// ...</spa=
n><span style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#606">One</span><span style=3D"color:#660">&g=
t;(</span><span style=3D"color:#000">a_red_thing</span><span style=3D"color=
:#660">);</span><span style=3D"color:#000"><br>hooray</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#606">Two</span><span style=3D"=
color:#660">&gt;(</span><span style=3D"color:#000">a_blue_thing</span><span=
 style=3D"color:#660">);</span></div></code></div><div><br></div></div><div=
><a href=3D"https://wandbox.org/permlink/ySWp3QWnqWIxylQN" target=3D"_blank=
" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/u=
rl?q\x3dhttps%3A%2F%2Fwandbox.org%2Fpermlink%2FySWp3QWnqWIxylQN\x26sa\x3dD\=
x26sntz\x3d1\x26usg\x3dAFQjCNElSWfWjtZRVeBk11bq3cQ4wDPhOg&#39;;return true;=
" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2=
Fwandbox.org%2Fpermlink%2FySWp3QWnqWIxylQN\x26sa\x3dD\x26sntz\x3d1\x26usg\x=
3dAFQjCNElSWfWjtZRVeBk11bq3cQ4wDPhOg&#39;;return true;">Here&#39;s the exam=
ple, complete and compilable.</a></div><div><br></div><div>=E2=80=93Arthur<=
/div></div></blockquote><div><br></div><div>Probably one thing that prevent=
 this usage is that `concept_` concept isn&#39;t concept at least when `hoo=
ray` is parsed, you will need use prefix `concept` to allow correct parsing=
 of this code (same as you need use `template` or `typename`).</div><div><b=
r></div><div>Another thing, why not use `some_concept&lt;M, T&gt;`?</div><d=
iv><br></div><div>Overall I think this was <span id=3D"result_box" class=3D=
"short_text" lang=3D"en"><span class=3D"">deliberately </span></span>done t=
o simplify whole design and avion any unexpected iterations, It would be ba=
d if concepts skyrocket to level of template metaprograming from beginning,=
 AFAIK right now you can&#39;t do any arbitrary ordering of concepts that d=
epends on metaprograming and this is good thing.<br></div><div> <br></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/0b82cc47-9dd1-41f1-80b4-3e1469aaa9a9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0b82cc47-9dd1-41f1-80b4-3e1469aaa9a9=
%40isocpp.org</a>.<br />

------=_Part_639_388732386.1533885897631--

------=_Part_638_172201033.1533885897630--

.


Author: florian.csdt@gmail.com
Date: Fri, 10 Aug 2018 00:38:15 -0700 (PDT)
Raw View
------=_Part_709_1247417356.1533886695449
Content-Type: multipart/alternative;
 boundary="----=_Part_710_752200746.1533886695450"

------=_Part_710_752200746.1533886695450
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le vendredi 10 ao=C3=BBt 2018 09:24:57 UTC+2, Marcin Jaczewski a =C3=A9crit=
 :
>
>
>
> On Friday, August 10, 2018 at 3:53:26 AM UTC+2, Arthur O'Dwyer wrote:
>>
>> On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote:
>>>
>>> I recently discovered that concepts must be defined at namespace scope.=
=20
>>> What is the reason for this? It seems like an arbitrary restriction to =
me,=20
>>> when alias templates and variable templates can appear at class scope.
>>>
>>> This realization came from thinking about passing concepts as template=
=20
>>> parameters. It currently is not possible. Template parameters can't be=
=20
>>> concepts; they can only be template template (type) parameters, type=20
>>> parameters, or value parameters. Wrapping the concept inside a struct=
=20
>>> doesn't work as well, since the concept must be defined at namespace sc=
ope.
>>>
>>
>>
>> Here's an example involving "member concept aliases" that I worked up th=
e=20
>> other day on Slack:
>>
>> struct One {
>>     template<Red T> static void f(T);
>>     template<class T> using concept concept_ =3D Red<T>;
>> };
>> struct Two {
>>     template<Blue T> static void f(T);
>>     template<class T> using concept concept_ =3D Blue<T>;
>> };
>>
>> template<class Meta, class T> requires(Meta::template concept_<T>)
>> void hooray(T t) {
>>     return Meta::f(t);
>> }
>>
>> // ...
>> hooray<One>(a_red_thing);
>> hooray<Two>(a_blue_thing);
>>
>> (It occurred to me that it is very convenient how neither `type` nor=20
>> `value` is a reserved word in C++; and that it is corresponding unfortun=
ate=20
>> that `concept` *will* be a keyword. Notice the use of `concept_` above.)
>>
>> Casey Carter pointed out that *almost* the same effect can be achieved=
=20
>> via
>>
>> struct One {
>>     template<Red T> static void f(T);
>> };
>> struct Two {
>>     template<Blue T> static void f(T);
>> };
>>
>> template<class Meta, class T> requires requires (T t) { Meta::f(t); }
>> void hooray(T t) {
>>     return Meta::f(t);
>> }
>>
>> // ...
>> hooray<One>(a_red_thing);
>> hooray<Two>(a_blue_thing);
>>
>> The difference between the "concept" approach and the "anonymous=20
>> requires-clause" approach has to do with subsumption rules.
>> Also, this smells a lot like smuggling a concept (e.g. `Red`) through a=
=20
>> function declaration (`One::f`), i.e., a sneaky technical workaround for=
 a=20
>> missing feature in the language, analogous to how we used to have to=20
>> smuggle variable templates through class templates (e.g. every type-trai=
t=20
>> ever).
>>
>> If you're willing to forgo subsumption (which I personally am, AFAIK),=
=20
>> then you can already achieve the goal of "member concepts" by simply=20
>> rewriting all your concepts as plain old variable templates. To the exte=
nt=20
>> that this doesn't work, it shows why we might want to add real member=20
>> concepts and concept aliases. To the extent that this does work, it show=
s=20
>> why we don't technically need the `concept` keyword at all.
>>
>> struct One {
>>     template<Red T> static void f(T);
>>     template<class T> static constexpr bool concept_ =3D Red<T>;
>> };
>> struct Two {
>>     template<Blue T> static void f(T);
>>     template<class T> static constexpr bool concept_ =3D Blue<T>;
>> };
>>
>> template<class Meta, class T> requires Meta::template concept_<T>
>> void hooray(T t) {
>>     return Meta::f(t);
>> }
>>
>> // ...
>> hooray<One>(a_red_thing);
>> hooray<Two>(a_blue_thing);
>>
>> Here's the example, complete and compilable.=20
>> <https://wandbox.org/permlink/ySWp3QWnqWIxylQN>
>>
>> =E2=80=93Arthur
>>
>
> Probably one thing that prevent this usage is that `concept_` concept=20
> isn't concept at least when `hooray` is parsed, you will need use prefix=
=20
> `concept` to allow correct parsing of this code (same as you need use=20
> `template` or `typename`).
>
> Another thing, why not use `some_concept<M, T>`?
>
> Overall I think this was deliberately done to simplify whole design and=
=20
> avion any unexpected iterations, It would be bad if concepts skyrocket to=
=20
> level of template metaprograming from beginning, AFAIK right now you can'=
t=20
> do any arbitrary ordering of concepts that depends on metaprograming and=
=20
> this is good thing.
>
>
As already said, allowing concepts as class members would most likely=20
simplify the rules (no corner cases).
This would also make the language more consistent.

I think the main problem would be that a concept could be "specialized": If=
=20
the concept is member of a class template. One could specialize the=20
template and change the definition of the concept.
I would say it is mostly fine for the compiler as the concept will be=20
different for each and every single instantiation of the template anyway.

Most importantly, this feature can be easily standardized afterwards:=20
current concepts are forward compatible with this.

--=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/ad47f87b-89e9-4fd5-ac41-3b4beca6047e%40isocpp.or=
g.

------=_Part_710_752200746.1533886695450
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le vendredi 10 ao=C3=BBt 2018 09:24:57 UTC+2, Marc=
in Jaczewski a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div dir=3D"ltr"><br><br>On Friday, August 10, 2018 at 3:53:26 AM UTC+2, =
Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr">On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I recently d=
iscovered that concepts must be defined at namespace scope. What is the rea=
son for this? It seems like an arbitrary restriction to me, when alias temp=
lates and variable templates can appear at class scope.<div><br></div><div>=
This realization came from thinking about passing concepts as template para=
meters. It currently is not possible. Template parameters can&#39;t be conc=
epts; they can only be template template (type) parameters, type parameters=
, or value parameters. Wrapping the concept inside a struct doesn&#39;t wor=
k as well, since the concept must be defined at namespace scope.</div></div=
></blockquote><div><br></div><div><br></div><div>Here&#39;s an example invo=
lving &quot;member concept aliases&quot; that I worked up the other day on =
Slack:</div><div><br></div><div><div style=3D"background-color:rgb(250,250,=
250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">One</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">template</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#606">Red</span><span style=3D"color:#000">=
 T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">static</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">void</span><span style=3D"color:#000"> f<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#000">T</span=
><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:#008">template</span><span style=3D"colo=
r:#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"co=
lor:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">using</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">concept</span><span style=3D"col=
or:#000"> concept_ </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Red</span><span style=3D=
"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"c=
olor:#660">&gt;;</span><span style=3D"color:#000"><br></span><span style=3D=
"color:#660">};</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#008">struct</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">Two</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#606">Blue</span><span style=3D"color:#000"> T</span><s=
pan style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">static</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">void</span><span style=3D"color:#000"> f</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">T</span><span styl=
e=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt=
;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">concept</span><span style=3D"color:#000"> c=
oncept_ </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Blue</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">=
&gt;;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">};</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#=
008">template</span><span style=3D"color:#660">&lt;</span><span style=3D"co=
lor:#008">class</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#606">Meta</span><span style=3D"color:#660">,</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">class</span><span style=3D"color:=
#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#=
000"> requires</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#606">Meta</span><span style=3D"color:#660">::</span><span style=3D"color=
:#008">template</span><span style=3D"color:#000"> concept_</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">&gt;)</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">void</span><span style=3D"color:#000"> hooray</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">T t</span><span st=
yle=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008">return</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Meta</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">f</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">t</span><span style=3D"color:#660">);</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#800">// ...</span><spa=
n style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#606">One</span><span style=3D"color:#660">&gt;(</s=
pan><span style=3D"color:#000">a_red_thing</span><span style=3D"color:#660"=
>);</span><span style=3D"color:#000"><br>hooray</span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#606">Two</span><span style=3D"color:=
#660">&gt;(</span><span style=3D"color:#000">a_blue_thing</span><span style=
=3D"color:#660">);</span></div></code></div><div><br></div></div><div>(It o=
ccurred to me that it is very convenient how neither `type` nor `value` is =
a reserved word in C++; and that it is corresponding unfortunate that `conc=
ept` <i>will</i> be a keyword. Notice the use of `concept_` above.)</div><d=
iv><br></div><div>Casey Carter pointed out that <i>almost</i> the same effe=
ct can be achieved via</div><div><br></div><div><div style=3D"background-co=
lor:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word=
"><code><div><span style=3D"color:#008">struct</span><span style=3D"color:#=
000"> </span><span style=3D"color:#606">One</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#606">Red</span><span style=
=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">static</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">void</span><span style=
=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">T</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#008">struct</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#606">Two</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#606">Blue</span><span=
 style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">static</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">void</span><span st=
yle=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">T</span><span style=3D"color:#660">);</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"c=
olor:#000"><br><br></span><span style=3D"color:#008">template</span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> requires requires </=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">T t</spa=
n><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#606">Meta</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">f</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">t</span><span style=3D"color:#660">);</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">}</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#008">void</span><span style=3D"color:#=
000"> hooray</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">T t</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">f</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">t</span><span style=3D"color=
:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#660">}</span><span style=3D"color:#000"><br><br></span><span style=3D"colo=
r:#800">// ...</span><span style=3D"color:#000"><br>hooray</span><span styl=
e=3D"color:#660">&lt;</span><span style=3D"color:#606">One</span><span styl=
e=3D"color:#660">&gt;(</span><span style=3D"color:#000">a_red_thing</span><=
span style=3D"color:#660">);</span><span style=3D"color:#000"><br>hooray</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Two</s=
pan><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">a_blu=
e_thing</span><span style=3D"color:#660">);</span></div></code></div><div><=
br></div></div><div>The difference between the &quot;concept&quot; approach=
 and the &quot;anonymous requires-clause&quot; approach has to do with subs=
umption rules.</div><div>Also, this smells a lot like smuggling a concept (=
e.g. `Red`) through a function declaration (`One::f`), i.e., a sneaky techn=
ical workaround for a missing feature in the language, analogous to how we =
used to have to smuggle variable templates through class templates (e.g. ev=
ery type-trait ever).</div><div><br></div><div>If you&#39;re willing to for=
go subsumption (which I personally am, AFAIK), then you can already achieve=
 the goal of &quot;member concepts&quot; by simply rewriting all your conce=
pts as plain old variable templates. To the extent that this doesn&#39;t wo=
rk, it shows why we might want to add real member concepts and concept alia=
ses. To the extent that this does work, it shows why we don&#39;t technical=
ly need the `concept` keyword at all.</div><div><br></div><div><div style=
=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187);wor=
d-wrap:break-word"><code><div><span style=3D"color:#008">struct</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#606">One</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Re=
d</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">static=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">void</=
span><span style=3D"color:#000"> f</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">T</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008"=
>template</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#008">class</span><span style=3D"color:#000"> T</span><span style=3D"color:=
#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">static</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">constexpr</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">bool</span><span style=3D"color:#000"> concept_ </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D=
"color:#606">Red</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#000">T</span><span style=3D"color:#660">&gt;;</span><span style=3D"=
color:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#008">struct</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Two</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Blue</span=
><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">static</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">void</span><s=
pan style=3D"color:#000"> f</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">T</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">c=
lass</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&=
gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">sta=
tic</span><span style=3D"color:#000"> </span><span style=3D"color:#008">con=
stexpr</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
bool</span><span style=3D"color:#000"> concept_ </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
06">Blue</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#=
000">T</span><span style=3D"color:#660">&gt;;</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#660">};</span><span style=3D"color:#00=
0"><br><br></span><span style=3D"color:#008">template</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">class</span><span style=3D"color:#000"> T</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"> requires </span><span sty=
le=3D"color:#606">Meta</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#008">template</span><span style=3D"color:#000"> concept_</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><s=
pan style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">void</span><span style=3D"color:#000"> hooray</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">T t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">return</span><span style=3D"color:#000"> =
</span><span style=3D"color:#606">Meta</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">f</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">t</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span=
 style=3D"color:#000"><br><br></span><span style=3D"color:#800">// ...</spa=
n><span style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#606">One</span><span style=3D"color:#660">&g=
t;(</span><span style=3D"color:#000">a_red_thing</span><span style=3D"color=
:#660">);</span><span style=3D"color:#000"><br>hooray</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#606">Two</span><span style=3D"=
color:#660">&gt;(</span><span style=3D"color:#000">a_blue_thing</span><span=
 style=3D"color:#660">);</span></div></code></div><div><br></div></div><div=
><a href=3D"https://wandbox.org/permlink/ySWp3QWnqWIxylQN" rel=3D"nofollow"=
 target=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www.google.com/u=
rl?q\x3dhttps%3A%2F%2Fwandbox.org%2Fpermlink%2FySWp3QWnqWIxylQN\x26sa\x3dD\=
x26sntz\x3d1\x26usg\x3dAFQjCNElSWfWjtZRVeBk11bq3cQ4wDPhOg&#39;;return true;=
" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2=
Fwandbox.org%2Fpermlink%2FySWp3QWnqWIxylQN\x26sa\x3dD\x26sntz\x3d1\x26usg\x=
3dAFQjCNElSWfWjtZRVeBk11bq3cQ4wDPhOg&#39;;return true;">Here&#39;s the exam=
ple, complete and compilable.</a></div><div><br></div><div>=E2=80=93Arthur<=
/div></div></blockquote><div><br></div><div>Probably one thing that prevent=
 this usage is that `concept_` concept isn&#39;t concept at least when `hoo=
ray` is parsed, you will need use prefix `concept` to allow correct parsing=
 of this code (same as you need use `template` or `typename`).</div><div><b=
r></div><div>Another thing, why not use `some_concept&lt;M, T&gt;`?</div><d=
iv><br></div><div>Overall I think this was <span lang=3D"en"><span>delibera=
tely </span></span>done to simplify whole design and avion any unexpected i=
terations, It would be bad if concepts skyrocket to level of template metap=
rograming from beginning, AFAIK right now you can&#39;t do any arbitrary or=
dering of concepts that depends on metaprograming and this is good thing.<b=
r></div><div> <br></div></div></blockquote><div><br></div><div>As already s=
aid, allowing concepts as class members would most likely simplify the rule=
s (no corner cases).</div><div>This would also make the language more consi=
stent.</div><div><br></div><div>I think the main problem would be that a co=
ncept could be &quot;specialized&quot;: If the concept is member of a class=
 template. One could specialize the template and change the definition of t=
he concept.</div><div>I would say it is mostly fine for the compiler as the=
 concept will be different for each and every single instantiation of the t=
emplate anyway.</div><div><br></div><div>Most importantly, this feature can=
 be easily standardized afterwards: current concepts are forward compatible=
 with this.<br></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/ad47f87b-89e9-4fd5-ac41-3b4beca6047e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ad47f87b-89e9-4fd5-ac41-3b4beca6047e=
%40isocpp.org</a>.<br />

------=_Part_710_752200746.1533886695450--

------=_Part_709_1247417356.1533886695449--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 10 Aug 2018 07:01:42 -0700 (PDT)
Raw View
------=_Part_744_1951159257.1533909702585
Content-Type: multipart/alternative;
 boundary="----=_Part_745_1321169249.1533909702586"

------=_Part_745_1321169249.1533909702586
Content-Type: text/plain; charset="UTF-8"

On Thursday, August 9, 2018 at 11:41:47 PM UTC-4, Justin Bassett wrote:
>
> Let me put it this way: I haven't found very good use-cases for concepts
> inside classes as of yet.  IMO, it is more consistent and logical, but
> that's not a use-case. However, I do believe that allowing concepts at
> class scope will encourage exploration, which I believe has potential to
> come up with useful techniques which we have not yet thought of.
>

And that's a very good reason *not* to do it.

So many things in C++ that we depend on are accidents, "useful techniques"
that don't really make intuitive sense and require expert-level thinking.
And the committee is trying to *reduce* that.

SFINAE was one such tool; concepts essentially replaces it. It is replaced
with a feature that is far easier to understand and use. It's much less of
a wart and is clearly a part of the language.

Template metaprogramming as a whole is such a feature. `constexpr`
functions have chipped away at it, and as such functions get more capable,
and as we get reflection in `constexpr` functions, we may finally be able
to abandon metaprogramming in favor of something that makes sense.

C++ needs less of people coming up with "useful techniques" by using random
tools in the language. What it needs is more "useful techniques" in the
language itself.

So even if a limitation may not seem necessary, unless you can come up with
a straightforward use that this limitation is impeding, we probably
shouldn't remove the limitation.

I do have some partial ideas, though. Aside from having the concept
> declared closer to the point of use,
>

Named concepts are not things that should be used for one-off cases. If
you're writing an actual `concept` declaration, there ought to be at least
2 templates that use it somewhere.


> I had a thought that maybe with reflection, perhaps requiring something
> like metaclasses, one could implement something like C++0x concepts as a
> library, where an interface describing all the required functions is passed
> in, and a concept with some other information is passed out.
>

That's not how C++0x concepts worked. There, you had a concept definition
(the sequence of expressions legal on a certain set of types), and you had
types. When you attempted to apply a concept constraint to one or more
types, the system would generate a "concept map", which was effectively an
invisible type wrapper around them. Implicit concept maps would just
forward the operations to the actual type's corresponding functions. But
you could write explicit concept maps against a particular concept/type
pairing, so that you wouldn't need `traits` classes and so forth.

To emulate that, you would need several things. You'd have to be able to
pass a concept to something that synthesizes the equivalent of a "concept
map". You'd need some way to reflect on a concept and generate functions
based on the expressions required by the concept (not an easy thing). And
you'd have to have some way to magically insert this "concept map" into
functions that constrain their parameters on a concept.

Being able to pass a concept around is only step 1 of this process. The
other steps seem exceedingly difficult, based on our current concept
design. Without those other steps, passing a concept around just isn't
useful.


> However, in my thoughts surrounding this, it's either necessary or
> extremely helpful for concepts to be allowed at class scope.
>
> On Thu, Aug 9, 2018 at 8:33 PM Justin Bassett <jbass...@gmail.com
> <javascript:>> wrote:
>
>> Casey Carter pointed out that *almost* the same effect can be achieved
>>> via
>>>
>>> struct One {
>>>     template<Red T> static void f(T);
>>> };
>>> struct Two {
>>>     template<Blue T> static void f(T);
>>> };
>>>
>>> template<class Meta, class T> requires requires (T t) { Meta::f(t); }
>>> void hooray(T t) {
>>>     return Meta::f(t);
>>> }
>>>
>>> // ...
>>> hooray<One>(a_red_thing);
>>> hooray<Two>(a_blue_thing);
>>>
>>>
>> The problem with this solution (and the one with variable templates) is
>> that you lose the nice error messages. With a direct concept, the
>> compilers give error messages that explain why the type doesn't mean the
>> concept. With these alternatives, the compilers just say, "It doesn't work
>> because Meta::f(t) wasn't valid" or "It doesn't work because concept_
>> was false". One could argue that it's a QOI issue, but I disagree, because
>> we discarded the information that we considered it an explicit concept.
>>
>>

--
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/26a06507-4d38-473c-8637-1372b51dd3a1%40isocpp.org.

------=_Part_745_1321169249.1533909702586
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, August 9, 2018 at 11:41:47 PM UTC-4, Justin B=
assett wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
Let me put it this way: I haven&#39;t found very good use-cases for concept=
s inside classes as of yet.=C2=A0

IMO,=C2=A0it is more consistent and logical, but that&#39;s not a use-case.=
 However, I do believe that allowing concepts at class scope will encourage=
 exploration, which I believe has potential to come up with useful techniqu=
es which we have not yet thought of.</div></blockquote><div><br></div><div>=
And that&#39;s a very good reason <i>not</i> to do it.</div><div><br></div>=
<div>So many things in C++ that we depend on are accidents, &quot;useful te=
chniques&quot; that don&#39;t really make intuitive sense and require exper=
t-level thinking. And the committee is trying to <i>reduce</i> that.</div><=
div><br></div><div>SFINAE was one such tool; concepts essentially replaces =
it. It is replaced with a feature that is far easier to understand and use.=
 It&#39;s much less of a wart and is clearly a part of the language.</div><=
div><br></div><div>Template metaprogramming as a whole is such a feature. `=
constexpr` functions have chipped away at it, and as such functions get mor=
e capable, and as we get reflection in `constexpr` functions, we may finall=
y be able to abandon metaprogramming in favor of something that makes sense=
..<br></div><div><br></div><div></div><div>C++ needs less of people coming u=
p with &quot;useful techniques&quot; by using random tools in the language.=
 What it needs is more &quot;useful techniques&quot; in the language itself=
..</div><div><br></div><div>So even if a limitation may not seem necessary, =
unless you can come up with a straightforward use that this limitation is i=
mpeding, we probably shouldn&#39;t remove the limitation.<br></div><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><=
/div><div>I do have some partial ideas, though. Aside from having the conce=
pt declared closer to the point of use,</div></div></blockquote><div><br></=
div><div>Named concepts are not things that should be used for one-off case=
s. If you&#39;re writing an actual `concept` declaration, there ought to be=
 at least 2 templates that use it somewhere.<br></div><div>=C2=A0</div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>I had a thou=
ght that maybe with reflection, perhaps requiring something like metaclasse=
s, one could implement something like C++0x concepts as a library, where an=
 interface describing all the required functions is passed in, and a concep=
t with some other information is passed out.</div></div></blockquote><div><=
br></div><div>That&#39;s not how C++0x concepts worked. There, you had a co=
ncept definition (the sequence of expressions legal on a certain set of typ=
es), and you had types. When you attempted to apply a concept constraint to=
 one or more types, the system would generate a &quot;concept map&quot;, wh=
ich was effectively an invisible type wrapper around them. Implicit concept=
 maps would just forward the operations to the actual type&#39;s correspond=
ing functions. But you could write explicit concept maps against a particul=
ar concept/type pairing, so that you wouldn&#39;t need `traits` classes and=
 so forth.</div><div><br></div><div>To emulate that, you would need several=
 things. You&#39;d have to be able to pass a concept to something that synt=
hesizes the equivalent of a &quot;concept map&quot;. You&#39;d need some wa=
y to reflect on a concept and generate functions based on the expressions r=
equired by the concept (not an easy thing). And you&#39;d have to have some=
 way to magically insert this &quot;concept map&quot; into functions that c=
onstrain their parameters on a concept.</div><div><br></div><div>Being able=
 to pass a concept around is only step 1 of this process. The other steps s=
eem exceedingly difficult, based on our current concept design. Without tho=
se other steps, passing a concept around just isn&#39;t useful.<br></div><d=
iv>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div>However, in my thoughts surrounding this, it&#39;s either necessary =
or extremely helpful for concepts to be allowed at class scope.</div></div>=
<br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Aug 9, 2018 at 8:33=
 PM Justin Bassett &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"ou5DWxMgDQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">jbass...@gmail.com</a>&gt; wrote:<br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div><div>Casey Carter pointed out that <=
i>almost</i> the same effect can be achieved via<br></div></div><div><br></=
div><div><div style=3D"background-color:rgb(250,250,250);border:1px solid r=
gb(187,187,187);word-wrap:break-word"><code><div><span style=3D"color:#008"=
>struct</span><span style=3D"color:#000"> </span><span style=3D"color:#606"=
>One</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">Red</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">static</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">void</span><span style=3D"color:#000"> f</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">T</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#660">};</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#008">struct</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#606">Two</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#606">Blue</span><span style=3D"color:#000"> T</span><span=
 style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">static</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">void</span><span style=3D"color:#000"> f</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">};</span><span style=3D"color:#000"><br><br></span><span st=
yle=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#008">class</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#606">Meta</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">class</span><span s=
tyle=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span st=
yle=3D"color:#000"> requires requires </span><span style=3D"color:#660">(</=
span><span style=3D"color:#000">T t</span><span style=3D"color:#660">)</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Meta</span><span=
 style=3D"color:#660">::</span><span style=3D"color:#000">f</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">t</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">}</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#008">void</span><span style=3D"color:#000"> hooray</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">T t</span><span style=3D"colo=
r:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">Meta</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">f</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">t</span><span style=3D"color:#660">);</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"><br><br></span><span style=3D"color:#800">// ...</span><span style=3D"=
color:#000"><br>hooray</span><span style=3D"color:#660">&lt;</span><span st=
yle=3D"color:#606">One</span><span style=3D"color:#660">&gt;(</span><span s=
tyle=3D"color:#000">a_red_thing</span><span style=3D"color:#660">);</span><=
span style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#606">Two</span><span style=3D"color:#660">&gt;(=
</span><span style=3D"color:#000">a_blue_thing</span><span style=3D"color:#=
660">);</span></div></code></div><div><br></div></div></div></blockquote><d=
iv><br></div><div>The problem with this solution (and the one with variable=
 templates) is that you lose the nice error messages. With a direct <font f=
ace=3D"monospace, monospace">concept</font>, the compilers give error messa=
ges that explain why the type doesn&#39;t mean the concept. With these alte=
rnatives, the compilers just say, &quot;It doesn&#39;t work because <font f=
ace=3D"monospace, monospace">Meta::f(t)</font> wasn&#39;t valid&quot; or &q=
uot;It doesn&#39;t work because <font face=3D"monospace, monospace">concept=
_</font> was false&quot;. One could argue that it&#39;s a QOI issue, but I =
disagree, because we discarded the information that we considered it an exp=
licit concept.</div><div><br></div></div></div>
</blockquote></div>
</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/26a06507-4d38-473c-8637-1372b51dd3a1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/26a06507-4d38-473c-8637-1372b51dd3a1=
%40isocpp.org</a>.<br />

------=_Part_745_1321169249.1533909702586--

------=_Part_744_1951159257.1533909702585--

.


Author: "T. C." <rs2740@gmail.com>
Date: Fri, 10 Aug 2018 11:54:31 -0700 (PDT)
Raw View
------=_Part_834_116525132.1533927271908
Content-Type: multipart/alternative;
 boundary="----=_Part_835_431680541.1533927271910"

------=_Part_835_431680541.1533927271910
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, August 10, 2018 at 3:38:15 AM UTC-4, floria...@gmail.com wrote:
>
>
>
> Le vendredi 10 ao=C3=BBt 2018 09:24:57 UTC+2, Marcin Jaczewski a =C3=A9cr=
it :
>>
>>
>>
>> On Friday, August 10, 2018 at 3:53:26 AM UTC+2, Arthur O'Dwyer wrote:
>>>
>>> On Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote=
:
>>>>
>>>> I recently discovered that concepts must be defined at namespace scope=
..=20
>>>> What is the reason for this? It seems like an arbitrary restriction to=
 me,=20
>>>> when alias templates and variable templates can appear at class scope.
>>>>
>>>> This realization came from thinking about passing concepts as template=
=20
>>>> parameters. It currently is not possible. Template parameters can't be=
=20
>>>> concepts; they can only be template template (type) parameters, type=
=20
>>>> parameters, or value parameters. Wrapping the concept inside a struct=
=20
>>>> doesn't work as well, since the concept must be defined at namespace s=
cope.
>>>>
>>>
>>>
>>> Here's an example involving "member concept aliases" that I worked up=
=20
>>> the other day on Slack:
>>>
>>> struct One {
>>>     template<Red T> static void f(T);
>>>     template<class T> using concept concept_ =3D Red<T>;
>>> };
>>> struct Two {
>>>     template<Blue T> static void f(T);
>>>     template<class T> using concept concept_ =3D Blue<T>;
>>> };
>>>
>>> template<class Meta, class T> requires(Meta::template concept_<T>)
>>> void hooray(T t) {
>>>     return Meta::f(t);
>>> }
>>>
>>> // ...
>>> hooray<One>(a_red_thing);
>>> hooray<Two>(a_blue_thing);
>>>
>>> (It occurred to me that it is very convenient how neither `type` nor=20
>>> `value` is a reserved word in C++; and that it is corresponding unfortu=
nate=20
>>> that `concept` *will* be a keyword. Notice the use of `concept_` above.=
)
>>>
>>> Casey Carter pointed out that *almost* the same effect can be achieved=
=20
>>> via
>>>
>>> struct One {
>>>     template<Red T> static void f(T);
>>> };
>>> struct Two {
>>>     template<Blue T> static void f(T);
>>> };
>>>
>>> template<class Meta, class T> requires requires (T t) { Meta::f(t); }
>>> void hooray(T t) {
>>>     return Meta::f(t);
>>> }
>>>
>>> // ...
>>> hooray<One>(a_red_thing);
>>> hooray<Two>(a_blue_thing);
>>>
>>> The difference between the "concept" approach and the "anonymous=20
>>> requires-clause" approach has to do with subsumption rules.
>>> Also, this smells a lot like smuggling a concept (e.g. `Red`) through a=
=20
>>> function declaration (`One::f`), i.e., a sneaky technical workaround fo=
r a=20
>>> missing feature in the language, analogous to how we used to have to=20
>>> smuggle variable templates through class templates (e.g. every type-tra=
it=20
>>> ever).
>>>
>>> If you're willing to forgo subsumption (which I personally am, AFAIK),=
=20
>>> then you can already achieve the goal of "member concepts" by simply=20
>>> rewriting all your concepts as plain old variable templates. To the ext=
ent=20
>>> that this doesn't work, it shows why we might want to add real member=
=20
>>> concepts and concept aliases. To the extent that this does work, it sho=
ws=20
>>> why we don't technically need the `concept` keyword at all.
>>>
>>> struct One {
>>>     template<Red T> static void f(T);
>>>     template<class T> static constexpr bool concept_ =3D Red<T>;
>>> };
>>> struct Two {
>>>     template<Blue T> static void f(T);
>>>     template<class T> static constexpr bool concept_ =3D Blue<T>;
>>> };
>>>
>>> template<class Meta, class T> requires Meta::template concept_<T>
>>> void hooray(T t) {
>>>     return Meta::f(t);
>>> }
>>>
>>> // ...
>>> hooray<One>(a_red_thing);
>>> hooray<Two>(a_blue_thing);
>>>
>>> Here's the example, complete and compilable.=20
>>> <https://wandbox.org/permlink/ySWp3QWnqWIxylQN>
>>>
>>> =E2=80=93Arthur
>>>
>>
>> Probably one thing that prevent this usage is that `concept_` concept=20
>> isn't concept at least when `hooray` is parsed, you will need use prefix=
=20
>> `concept` to allow correct parsing of this code (same as you need use=20
>> `template` or `typename`).
>>
>> Another thing, why not use `some_concept<M, T>`?
>>
>> Overall I think this was deliberately done to simplify whole design and=
=20
>> avion any unexpected iterations, It would be bad if concepts skyrocket t=
o=20
>> level of template metaprograming from beginning, AFAIK right now you can=
't=20
>> do any arbitrary ordering of concepts that depends on metaprograming and=
=20
>> this is good thing.
>>
>>
> As already said, allowing concepts as class members would most likely=20
> simplify the rules (no corner cases).
> This would also make the language more consistent.
>
> I think the main problem would be that a concept could be "specialized":=
=20
> If the concept is member of a class template. One could specialize the=20
> template and change the definition of the concept.
> I would say it is mostly fine for the compiler as the concept will be=20
> different for each and every single instantiation of the template anyway.
>

That's an excellent reason to not permit this. Constraint normalization and=
=20
subsumption checking operate on the concept's definition *before*=20
instantiation, and so rely on a concept having a single unique definition.=
=20
If you can have arbitrarily many definitions for what appears to be the=20
same concept, how exactly do you normalize it and check for subsumption?

If you don't need subsumption checking and normalization, then you can just=
=20
use a static constexpr variable template.=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/b2f41eea-c62a-4b6d-878d-8b98570d84ea%40isocpp.or=
g.

------=_Part_835_431680541.1533927271910
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, August 10, 2018 at 3:38:15 AM UTC-4, fl=
oria...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><br><br>Le vendredi 10 ao=C3=BBt 2018 09:24:57 UTC+2, Marcin Jac=
zewski a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><br><br>On Friday, August 10, 2018 at 3:53:26 AM UTC+2, Arthur O&#=
39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On =
Wednesday, August 8, 2018 at 10:07:24 PM UTC-7, Justin Bassett wrote:<block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I recently discovered th=
at concepts must be defined at namespace scope. What is the reason for this=
? It seems like an arbitrary restriction to me, when alias templates and va=
riable templates can appear at class scope.<div><br></div><div>This realiza=
tion came from thinking about passing concepts as template parameters. It c=
urrently is not possible. Template parameters can&#39;t be concepts; they c=
an only be template template (type) parameters, type parameters, or value p=
arameters. Wrapping the concept inside a struct doesn&#39;t work as well, s=
ince the concept must be defined at namespace scope.</div></div></blockquot=
e><div><br></div><div><br></div><div>Here&#39;s an example involving &quot;=
member concept aliases&quot; that I worked up the other day on Slack:</div>=
<div><br></div><div><div style=3D"background-color:rgb(250,250,250);border:=
1px solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"=
color:#008">struct</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">One</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#606">Red</span><span style=3D"color:#000"> T</span><sp=
an style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">static</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">void</span><span style=3D"color:#000"> f</span><span =
style=3D"color:#660">(</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#008">class</span><span style=3D"color:#000"> T=
</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">using</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">concept</span><span style=3D"color:#000"> co=
ncept_ </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#606">Red</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&g=
t;;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">=
};</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">s=
truct</span><span style=3D"color:#000"> </span><span style=3D"color:#606">T=
wo</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"colo=
r:#008">template</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#606">Blue</span><span style=3D"color:#000"> T</span><span style=3D"=
color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#008">static</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#008">void</span><span style=3D"color:#000"> f</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#000">T</span><span style=3D"color:#6=
60">);</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span=
 style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">using</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">concept</span><span style=3D"color:#000"> concept_ </spa=
n><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><=
span style=3D"color:#606">Blue</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;;</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br><br></span><span style=3D"color:#008">template=
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Meta=
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</spa=
n><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> require=
s</span><span style=3D"color:#660">(</span><span style=3D"color:#606">Meta<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#000"> concept_</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660=
">&gt;)</span><span style=3D"color:#000"><br></span><span style=3D"color:#0=
08">void</span><span style=3D"color:#000"> hooray</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">T t</span><span style=3D"color:#=
660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color:#008">return</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">Meta</span><span style=3D"color:#660">::</span><span style=3D"c=
olor:#000">f</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">t</span><span style=3D"color:#660">);</span><span style=3D"color:#000=
"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000">=
<br><br></span><span style=3D"color:#800">// ...</span><span style=3D"color=
:#000"><br>hooray</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#606">One</span><span style=3D"color:#660">&gt;(</span><span styl=
e=3D"color:#000">a_red_thing</span><span style=3D"color:#660">);</span><spa=
n style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#606">Two</span><span style=3D"color:#660">&gt;(</s=
pan><span style=3D"color:#000">a_blue_thing</span><span style=3D"color:#660=
">);</span></div></code></div><div><br></div></div><div>(It occurred to me =
that it is very convenient how neither `type` nor `value` is a reserved wor=
d in C++; and that it is corresponding unfortunate that `concept` <i>will</=
i> be a keyword. Notice the use of `concept_` above.)</div><div><br></div><=
div>Casey Carter pointed out that <i>almost</i> the same effect can be achi=
eved via</div><div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><=
span style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><=
span style=3D"color:#606">One</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0=
 </span><span style=3D"color:#008">template</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#606">Red</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">static</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">void</span><span style=3D"color:#000"> =
f</span><span style=3D"color:#660">(</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#008">struct</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Two</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">template</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#606">Blue</span><span style=3D"color:=
#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">static</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">void</span><span style=3D"color:#00=
0"> f</span><span style=3D"color:#660">(</span><span style=3D"color:#000">T=
</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><b=
r></span><span style=3D"color:#008">template</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#=
000"> </span><span style=3D"color:#606">Meta</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">cl=
ass</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> requires requires </span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">T t</span><span style=3D=
"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Meta</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">f</span><span style=3D"color:#660">(</span><span style=3D"color:#000">t</=
span><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">void</span><span style=3D"color:#000"> hooray</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">T t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">return</span><span style=3D"color:#000"> =
</span><span style=3D"color:#606">Meta</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">f</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">t</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span=
 style=3D"color:#000"><br><br></span><span style=3D"color:#800">// ...</spa=
n><span style=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#606">One</span><span style=3D"color:#660">&g=
t;(</span><span style=3D"color:#000">a_red_thing</span><span style=3D"color=
:#660">);</span><span style=3D"color:#000"><br>hooray</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#606">Two</span><span style=3D"=
color:#660">&gt;(</span><span style=3D"color:#000">a_blue_thing</span><span=
 style=3D"color:#660">);</span></div></code></div><div><br></div></div><div=
>The difference between the &quot;concept&quot; approach and the &quot;anon=
ymous requires-clause&quot; approach has to do with subsumption rules.</div=
><div>Also, this smells a lot like smuggling a concept (e.g. `Red`) through=
 a function declaration (`One::f`), i.e., a sneaky technical workaround for=
 a missing feature in the language, analogous to how we used to have to smu=
ggle variable templates through class templates (e.g. every type-trait ever=
).</div><div><br></div><div>If you&#39;re willing to forgo subsumption (whi=
ch I personally am, AFAIK), then you can already achieve the goal of &quot;=
member concepts&quot; by simply rewriting all your concepts as plain old va=
riable templates. To the extent that this doesn&#39;t work, it shows why we=
 might want to add real member concepts and concept aliases. To the extent =
that this does work, it shows why we don&#39;t technically need the `concep=
t` keyword at all.</div><div><br></div><div><div style=3D"background-color:=
rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><c=
ode><div><span style=3D"color:#008">struct</span><span style=3D"color:#000"=
> </span><span style=3D"color:#606">One</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#606">Red</span><span style=3D"=
color:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">static</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">void</span><span style=3D"col=
or:#000"> f</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">T</span><span style=3D"color:#660">);</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span=
 style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">static</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">constexpr</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">bool</span><span=
 style=3D"color:#000"> concept_ </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Red</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><spa=
n style=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#660">};</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">Two</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">template</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#606">Blue</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">static</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">void</span><span style=3D"color:#000"> f=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">T</spa=
n><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=A0=
 =C2=A0 </span><span style=3D"color:#008">template</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"c=
olor:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">static</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">constexpr</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">bool</span><span style=3D"c=
olor:#000"> concept_ </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#606">Blue</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#660">};</span><span style=3D"color:#000"><br><br></span><span =
style=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">class</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#606">Meta</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">class</span><span=
 style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span =
style=3D"color:#000"> requires </span><span style=3D"color:#606">Meta</span=
><span style=3D"color:#660">::</span><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> concept_</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt=
;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">vo=
id</span><span style=3D"color:#000"> hooray</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">T t</span><span style=3D"color:#660">)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> </span><span style=3D"color:=
#606">Meta</span><span style=3D"color:#660">::</span><span style=3D"color:#=
000">f</span><span style=3D"color:#660">(</span><span style=3D"color:#000">=
t</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><b=
r></span><span style=3D"color:#800">// ...</span><span style=3D"color:#000"=
><br>hooray</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#606">One</span><span style=3D"color:#660">&gt;(</span><span style=3D"col=
or:#000">a_red_thing</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br>hooray</span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#606">Two</span><span style=3D"color:#660">&gt;(</span><sp=
an style=3D"color:#000">a_blue_thing</span><span style=3D"color:#660">);</s=
pan></div></code></div><div><br></div></div><div><a href=3D"https://wandbox=
..org/permlink/ySWp3QWnqWIxylQN" rel=3D"nofollow" target=3D"_blank" onmoused=
own=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwandb=
ox.org%2Fpermlink%2FySWp3QWnqWIxylQN\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQj=
CNElSWfWjtZRVeBk11bq3cQ4wDPhOg&#39;;return true;" onclick=3D"this.href=3D&#=
39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fwandbox.org%2Fpermlink%2Fy=
SWp3QWnqWIxylQN\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNElSWfWjtZRVeBk11bq3=
cQ4wDPhOg&#39;;return true;">Here&#39;s the example, complete and compilabl=
e.</a></div><div><br></div><div>=E2=80=93Arthur</div></div></blockquote><di=
v><br></div><div>Probably one thing that prevent this usage is that `concep=
t_` concept isn&#39;t concept at least when `hooray` is parsed, you will ne=
ed use prefix `concept` to allow correct parsing of this code (same as you =
need use `template` or `typename`).</div><div><br></div><div>Another thing,=
 why not use `some_concept&lt;M, T&gt;`?</div><div><br></div><div>Overall I=
 think this was <span lang=3D"en"><span>deliberately </span></span>done to =
simplify whole design and avion any unexpected iterations, It would be bad =
if concepts skyrocket to level of template metaprograming from beginning, A=
FAIK right now you can&#39;t do any arbitrary ordering of concepts that dep=
ends on metaprograming and this is good thing.<br></div><div> <br></div></d=
iv></blockquote><div><br></div><div>As already said, allowing concepts as c=
lass members would most likely simplify the rules (no corner cases).</div><=
div>This would also make the language more consistent.</div><div><br></div>=
<div>I think the main problem would be that a concept could be &quot;specia=
lized&quot;: If the concept is member of a class template. One could specia=
lize the template and change the definition of the concept.</div><div>I wou=
ld say it is mostly fine for the compiler as the concept will be different =
for each and every single instantiation of the template anyway.</div></div>=
</blockquote><div><br></div><div>That&#39;s an excellent reason to not perm=
it this. Constraint normalization and subsumption checking operate on the c=
oncept&#39;s definition *before* instantiation, and so rely on a concept ha=
ving a single unique definition. If you can have arbitrarily many definitio=
ns for what appears to be the same concept, how exactly do you normalize it=
 and check for subsumption?</div><div><br></div><div>If you don&#39;t need =
subsumption checking and normalization, then you can just use a static cons=
texpr variable template.=C2=A0</div><div><br></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/b2f41eea-c62a-4b6d-878d-8b98570d84ea%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b2f41eea-c62a-4b6d-878d-8b98570d84ea=
%40isocpp.org</a>.<br />

------=_Part_835_431680541.1533927271910--

------=_Part_834_116525132.1533927271908--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 11 Aug 2018 06:14:45 -0700 (PDT)
Raw View
------=_Part_1007_376465988.1533993285685
Content-Type: multipart/alternative;
 boundary="----=_Part_1008_695635715.1533993285685"

------=_Part_1008_695635715.1533993285685
Content-Type: text/plain; charset="UTF-8"


>
>
> That's an excellent reason to not permit this. Constraint normalization
> and subsumption checking operate on the concept's definition *before*
> instantiation, and so rely on a concept having a single unique definition.
> If you can have arbitrarily many definitions for what appears to be the
> same concept, how exactly do you normalize it and check for subsumption?
>

I don't think this is a valid concern. A concept inside a class would have
to be accessed using Class<MyType>::theConcept, and in doing so the actual
template parameters are already known.
Obviously MyType can be a dependant type if the concept is used in template
code, but at the time of template instantiation the actual value of MyType
will be known anyway.

As in my example above it seems reasonable to believe that the main use of
concepts in classes would be to specify characteristics of parameters to
template functions in the same class. It does not seem important to define
a concept in a class if it is not used as requirements in its own methods
or nested classes.

Someone rasied the objection that we should not allow concepts in classes
because we can't find a use case for it. I totally disagree with this idea.
Finding interesting uses for a feature is a main driver for innovation. If
we didn't have SFINAE we might not have worked so hard to get concepts to
get a better implementation of that type of overload selection. If we had
had variable templates from the beginning we would not have to write _v on
all our type traits now. Template variables were excluded from C++98
because Bjarne didn't see any use for them (he stated this in a private
mail to me long time ago). I would argue that to exclude this possibility
we need a compelling example that it doesn't work, or is immensely hard to
implement. I think I debunked the attempt made in the previous post, but
there could be some issues related to constructor deduction guides (if
constructors use class local concepts). This has to be investigated and if
issues are found there may have to be provisions in the standard text
regarding how to handle such situations.

--
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/f5cef26a-d3be-4c4b-ae31-895a4adb38e8%40isocpp.org.

------=_Part_1008_695635715.1533993285685
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><br></div><div>That&#39;s an excellent reason to not permit this. =
Constraint normalization and subsumption checking operate on the concept&#3=
9;s definition *before* instantiation, and so rely on a concept having a si=
ngle unique definition. If you can have arbitrarily many definitions for wh=
at appears to be the same concept, how exactly do you normalize it and chec=
k for subsumption?</div></div></blockquote><div><br></div><div>I don&#39;t =
think this is a valid concern. A concept inside a class would have to be ac=
cessed using Class&lt;MyType&gt;::theConcept, and in doing so the actual te=
mplate parameters are already known.</div><div>Obviously MyType can be a de=
pendant type if the concept is used in template code, but at the time of te=
mplate instantiation the actual value of MyType will be known anyway.</div>=
<div><br></div><div>As in my example above it seems reasonable to believe t=
hat the main use of concepts in classes would be to specify characteristics=
 of parameters to template functions in the same class. It does not seem im=
portant to define a concept in a class if it is not used as requirements in=
 its own methods or nested classes.</div><div><br></div><div>Someone rasied=
 the objection that we should not allow concepts in classes because we can&=
#39;t find a use case for it. I totally disagree with this idea. Finding in=
teresting uses for a feature is a main driver for innovation. If we didn&#3=
9;t have SFINAE we might not have worked so hard to get concepts to get a b=
etter implementation of that type of overload selection. If we had had vari=
able templates from the beginning we would not have to write _v on all our =
type traits now. Template variables were excluded from C++98 because Bjarne=
 didn&#39;t see any use for them (he stated this in a private mail to me lo=
ng time ago). I would argue that to exclude this possibility we need a comp=
elling example that it doesn&#39;t work, or is immensely hard to implement.=
 I think I debunked the attempt made in the previous post, but there could =
be some issues related to constructor deduction guides (if constructors use=
 class local concepts). This has to be investigated and if issues are found=
 there may have to be provisions in the standard text regarding how to hand=
le such situations.</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/f5cef26a-d3be-4c4b-ae31-895a4adb38e8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f5cef26a-d3be-4c4b-ae31-895a4adb38e8=
%40isocpp.org</a>.<br />

------=_Part_1008_695635715.1533993285685--

------=_Part_1007_376465988.1533993285685--

.


Author: "T. C." <rs2740@gmail.com>
Date: Sat, 11 Aug 2018 07:39:34 -0700 (PDT)
Raw View
------=_Part_1069_89385992.1533998374505
Content-Type: multipart/alternative;
 boundary="----=_Part_1070_390629654.1533998374505"

------=_Part_1070_390629654.1533998374505
Content-Type: text/plain; charset="UTF-8"



On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:
>
>
>> That's an excellent reason to not permit this. Constraint normalization
>> and subsumption checking operate on the concept's definition *before*
>> instantiation, and so rely on a concept having a single unique definition.
>> If you can have arbitrarily many definitions for what appears to be the
>> same concept, how exactly do you normalize it and check for subsumption?
>>
>
> I don't think this is a valid concern. A concept inside a class would have
> to be accessed using Class<MyType>::theConcept, and in doing so the actual
> template parameters are already known.
> Obviously MyType can be a dependant type if the concept is used in
> template code, but at the time of template instantiation the actual value
> of MyType will be known anyway.
>

Assuming that X, Y, and Z are concepts,

template<class T> struct C {
    template<class U> concept Foo = X<U> && Y<U> && Z<U>;
};

template<> struct C<int> {
    template<class U> concept Foo = X<U>;
};

template<class T>
    requires C<T>::Foo<T>
void f(T);   //#1

template<class T>
    requires X<T> && Y<T>
void f(T);  // #2

Your position is #1 is less constrained than #2 for some template
parameters and more constrained for others?

--
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/54c3f080-b581-4f3e-8af1-6089adb3ffc9%40isocpp.org.

------=_Part_1070_390629654.1533998374505
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, =
Bengt Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br=
></div><div>That&#39;s an excellent reason to not permit this. Constraint n=
ormalization and subsumption checking operate on the concept&#39;s definiti=
on *before* instantiation, and so rely on a concept having a single unique =
definition. If you can have arbitrarily many definitions for what appears t=
o be the same concept, how exactly do you normalize it and check for subsum=
ption?</div></div></blockquote><div><br></div><div>I don&#39;t think this i=
s a valid concern. A concept inside a class would have to be accessed using=
 Class&lt;MyType&gt;::theConcept, and in doing so the actual template param=
eters are already known.</div><div>Obviously MyType can be a dependant type=
 if the concept is used in template code, but at the time of template insta=
ntiation the actual value of MyType will be known anyway.</div></div></bloc=
kquote><div><br></div><div>Assuming that X, Y, and Z are concepts,</div><di=
v><br></div><div>template&lt;class T&gt; struct C {</div><div>=C2=A0 =C2=A0=
 template&lt;class U&gt; concept Foo =3D X&lt;U&gt; &amp;&amp; Y&lt;U&gt; &=
amp;&amp; Z&lt;U&gt;;</div><div>};</div><div><br></div><div>template&lt;&gt=
; struct C&lt;int&gt; {</div><div>=C2=A0 =C2=A0 template&lt;class U&gt; con=
cept Foo =3D X&lt;U&gt;;</div><div>};</div><div><br></div><div>template&lt;=
class T&gt;</div><div>=C2=A0 =C2=A0 requires C&lt;T&gt;::Foo&lt;T&gt;</div>=
<div>void f(T);=C2=A0 =C2=A0//#1</div><div><br></div><div>template&lt;class=
 T&gt;</div><div>=C2=A0 =C2=A0 requires X&lt;T&gt; &amp;&amp; Y&lt;T&gt;</d=
iv><div>void f(T);=C2=A0 // #2</div><div><br></div><div>Your position is #1=
 is less constrained than #2 for some template parameters and more constrai=
ned for others?</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/54c3f080-b581-4f3e-8af1-6089adb3ffc9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/54c3f080-b581-4f3e-8af1-6089adb3ffc9=
%40isocpp.org</a>.<br />

------=_Part_1070_390629654.1533998374505--

------=_Part_1069_89385992.1533998374505--

.


Author: florian.csdt@gmail.com
Date: Sat, 11 Aug 2018 08:01:41 -0700 (PDT)
Raw View
------=_Part_1080_260385920.1533999702040
Content-Type: multipart/alternative;
 boundary="----=_Part_1081_1544444038.1533999702041"

------=_Part_1081_1544444038.1533999702041
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le samedi 11 ao=C3=BBt 2018 16:39:34 UTC+2, T. C. a =C3=A9crit :
>
>
>
> On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:
>>
>>
>>> That's an excellent reason to not permit this. Constraint normalization=
=20
>>> and subsumption checking operate on the concept's definition *before*=
=20
>>> instantiation, and so rely on a concept having a single unique definiti=
on.=20
>>> If you can have arbitrarily many definitions for what appears to be the=
=20
>>> same concept, how exactly do you normalize it and check for subsumption=
?
>>>
>>
>> I don't think this is a valid concern. A concept inside a class would=20
>> have to be accessed using Class<MyType>::theConcept, and in doing so the=
=20
>> actual template parameters are already known.
>> Obviously MyType can be a dependant type if the concept is used in=20
>> template code, but at the time of template instantiation the actual valu=
e=20
>> of MyType will be known anyway.
>>
>
> Assuming that X, Y, and Z are concepts,
>
> template<class T> struct C {
>     template<class U> concept Foo =3D X<U> && Y<U> && Z<U>;
> };
>
> template<> struct C<int> {
>     template<class U> concept Foo =3D X<U>;
> };
>
> template<class T>
>     requires C<T>::Foo<T>
> void f(T);   //#1
>
> template<class T>
>     requires X<T> && Y<T>
> void f(T);  // #2
>
> Your position is #1 is less constrained than #2 for some template=20
> parameters and more constrained for others?
>

Well, my feeling is: no function would be more constrain than the other.
Remember that concepts are not totally ordered.

It would be used more like this:
template <class T>
struct Bar {
  template <class U>
    requires C<T>::Foo<U>
  void f(U); //#1

  template <class U>
    requires X<U> && Y<T>
  void f(U); //#2
};

Now, things are different, for Bar<int>, #2 would be more constrained,=20
while for Bar<T>, #1 would be more constrained.

--=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/a4cd296d-13be-431b-85fe-c84d98f673e6%40isocpp.or=
g.

------=_Part_1081_1544444038.1533999702041
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le samedi 11 ao=C3=BBt 2018 16:39:34 UTC+2, T. C. =
a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><br><br>On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gusta=
fsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>That=
&#39;s an excellent reason to not permit this. Constraint normalization and=
 subsumption checking operate on the concept&#39;s definition *before* inst=
antiation, and so rely on a concept having a single unique definition. If y=
ou can have arbitrarily many definitions for what appears to be the same co=
ncept, how exactly do you normalize it and check for subsumption?</div></di=
v></blockquote><div><br></div><div>I don&#39;t think this is a valid concer=
n. A concept inside a class would have to be accessed using Class&lt;MyType=
&gt;::theConcept, and in doing so the actual template parameters are alread=
y known.</div><div>Obviously MyType can be a dependant type if the concept =
is used in template code, but at the time of template instantiation the act=
ual value of MyType will be known anyway.</div></div></blockquote><div><br>=
</div><div>Assuming that X, Y, and Z are concepts,</div><div><br></div><div=
>template&lt;class T&gt; struct C {</div><div>=C2=A0 =C2=A0 template&lt;cla=
ss U&gt; concept Foo =3D X&lt;U&gt; &amp;&amp; Y&lt;U&gt; &amp;&amp; Z&lt;U=
&gt;;</div><div>};</div><div><br></div><div>template&lt;&gt; struct C&lt;in=
t&gt; {</div><div>=C2=A0 =C2=A0 template&lt;class U&gt; concept Foo =3D X&l=
t;U&gt;;</div><div>};</div><div><br></div><div>template&lt;class T&gt;</div=
><div>=C2=A0 =C2=A0 requires C&lt;T&gt;::Foo&lt;T&gt;</div><div>void f(T);=
=C2=A0 =C2=A0//#1</div><div><br></div><div>template&lt;class T&gt;</div><di=
v>=C2=A0 =C2=A0 requires X&lt;T&gt; &amp;&amp; Y&lt;T&gt;</div><div>void f(=
T);=C2=A0 // #2</div><div><br></div><div>Your position is #1 is less constr=
ained than #2 for some template parameters and more constrained for others?=
</div></div></blockquote><div><br></div><div>Well, my feeling is: no functi=
on would be more constrain than the other.</div><div>Remember that concepts=
 are not totally ordered.</div><div><br></div><div>It would be used more li=
ke this:</div><div><div style=3D"background-color: rgb(250, 250, 250); bord=
er-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overf=
low-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">template</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">class<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">Bar</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">template</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 requires C=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">U</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">U</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//#1</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> U</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>=C2=A0 =C2=A0 requires X</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">U</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> Y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">U</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
/#2</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div><br>Now, things are different, for Bar&lt;int&gt;, #2 would be mor=
e constrained, while for Bar&lt;T&gt;, #1 would be more constrained.<br></d=
iv></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/a4cd296d-13be-431b-85fe-c84d98f673e6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a4cd296d-13be-431b-85fe-c84d98f673e6=
%40isocpp.org</a>.<br />

------=_Part_1081_1544444038.1533999702041--

------=_Part_1080_260385920.1533999702040--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 11 Aug 2018 08:18:47 -0700 (PDT)
Raw View
------=_Part_1065_1054395461.1534000727714
Content-Type: multipart/alternative;
 boundary="----=_Part_1066_647505863.1534000727715"

------=_Part_1066_647505863.1534000727715
Content-Type: text/plain; charset="UTF-8"

On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:
>
>
>> That's an excellent reason to not permit this. Constraint normalization
>> and subsumption checking operate on the concept's definition *before*
>> instantiation, and so rely on a concept having a single unique definition.
>> If you can have arbitrarily many definitions for what appears to be the
>> same concept, how exactly do you normalize it and check for subsumption?
>>
>
> I don't think this is a valid concern. A concept inside a class would have
> to be accessed using Class<MyType>::theConcept, and in doing so the actual
> template parameters are already known.
> Obviously MyType can be a dependant type if the concept is used in
> template code, but at the time of template instantiation the actual value
> of MyType will be known anyway.
>
> As in my example above it seems reasonable to believe that the main use of
> concepts in classes would be to specify characteristics of parameters to
> template functions in the same class. It does not seem important to define
> a concept in a class if it is not used as requirements in its own methods
> or nested classes.
>

> Someone rasied the objection that we should not allow concepts in classes
> because we can't find a use case for it. I totally disagree with this idea.
> Finding interesting uses for a feature is a main driver for innovation. If
> we didn't have SFINAE we might not have worked so hard to get concepts to
> get a better implementation of that type of overload selection.
>

I disagree with that. Without SFINAE, we would still have a genuine need
for concepts. Indeed, without SFINAE, we would have more of a need, since
we'd have to employ even more complex, expert-only ways of doing that kind
of stuff.

If we had had variable templates from the beginning we would not have to
> write _v on all our type traits now.
>
Template variables were excluded from C++98 because Bjarne didn't see any
> use for them (he stated this in a private mail to me long time ago).
>

You've been using C++11 for too long. Bjarne was right; variable templates
in C++98 were not useful.

Variable templates are not useful by themselves; what makes them useful is
a combination of language features. Specifically, `constexpr` and `inline`
variables. Without both of those features, you wouldn't really be able to
replace type traits with variable templates. So we'd have still had to wait
until C++17.

I get the general thrust of what you're saying. But my point is that all of
those possible uses for class-scoped concepts are either minor conveniences
(scoping the name) or things that should be done with *actual features*,
not hacks and kludges that manage to accomplish a useful effect. C++ is
being updated with greater frequency now than in the C++98 days. We don't
need to allow everything on the assumption that someone might find a use
for it. We can do "enough" and then expand next time if a genuine need
emerges.

After all, that's what prompted the development of `inline` variables in
the first place. We had variable templates in C++14 and `constexpr`
variables in C++11. One more feature was needed to create the "encapsulated
expression" concept.

I would argue that to exclude this possibility we need a compelling example
> that it doesn't work, or is immensely hard to implement. I think I debunked
> the attempt made in the previous post, but there could be some issues
> related to constructor deduction guides (if constructors use class local
> concepts). This has to be investigated and if issues are found there may
> have to be provisions in the standard text regarding how to handle such
> situations.
>

--
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/dd36c1a5-70d6-41ef-95ae-dfd3ed000f33%40isocpp.org.

------=_Part_1066_647505863.1534000727715
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gu=
stafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><=
div>That&#39;s an excellent reason to not permit this. Constraint normaliza=
tion and subsumption checking operate on the concept&#39;s definition *befo=
re* instantiation, and so rely on a concept having a single unique definiti=
on. If you can have arbitrarily many definitions for what appears to be the=
 same concept, how exactly do you normalize it and check for subsumption?</=
div></div></blockquote><div><br></div><div>I don&#39;t think this is a vali=
d concern. A concept inside a class would have to be accessed using Class&l=
t;MyType&gt;::theConcept, and in doing so the actual template parameters ar=
e already known.</div><div>Obviously MyType can be a dependant type if the =
concept is used in template code, but at the time of template instantiation=
 the actual value of MyType will be known anyway.</div><div><br></div><div>=
As in my example above it seems reasonable to believe that the main use of =
concepts in classes would be to specify characteristics of parameters to te=
mplate functions in the same class. It does not seem important to define a =
concept in a class if it is not used as requirements in its own methods or =
nested classes. <br></div></div></blockquote><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>Someone rasied the obje=
ction that we should not allow concepts in classes because we can&#39;t fin=
d a use case for it. I totally disagree with this idea. Finding interesting=
 uses for a feature is a main driver for innovation. If we didn&#39;t have =
SFINAE we might not have worked so hard to get concepts to get a better imp=
lementation of that type of overload selection.</div></div></blockquote><di=
v><br></div><div>I disagree with that. Without SFINAE, we would still have =
a genuine need for concepts. Indeed, without SFINAE, we would have more of =
a need, since we&#39;d have to employ even more complex, expert-only ways o=
f doing that kind of stuff.<br></div><div><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div>If we had had variable template=
s from the beginning we would not have to write _v on all our type traits n=
ow. <br></div></div></blockquote><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr"><div>Template variables were excluded from C++98 becaus=
e Bjarne didn&#39;t see any use for them (he stated this in a private mail =
to me long time ago).</div></div></blockquote><div><br></div><div>You&#39;v=
e been using C++11 for too long. Bjarne was right; variable templates in C+=
+98 were not useful.</div><div><br></div><div>Variable templates are not us=
eful by themselves; what makes them useful is a combination of language fea=
tures. Specifically, `constexpr` and `inline` variables. Without both of th=
ose features, you wouldn&#39;t really be able to replace type traits with v=
ariable templates. So we&#39;d have still had to wait until C++17.</div><di=
v><br></div><div>I get the general thrust of what you&#39;re saying. But my=
 point is that all of those possible uses for class-scoped concepts are eit=
her minor conveniences (scoping the name) or things that should be done wit=
h <i>actual features</i>, not hacks and kludges that manage to accomplish a=
 useful effect. C++ is being updated with greater frequency now than in the=
 C++98 days. We don&#39;t need to allow everything on the assumption that s=
omeone might find a use for it. We can do &quot;enough&quot; and then expan=
d next time if a genuine need emerges.</div><div><br></div><div>After all, =
that&#39;s what prompted the development of `inline` variables in the first=
 place. We had variable templates in C++14 and `constexpr` variables in C++=
11. One more feature was needed to create the &quot;encapsulated expression=
&quot; concept.<br></div><div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div>I would argue that to exclude this possibil=
ity we need a compelling example that it doesn&#39;t work, or is immensely =
hard to implement. I think I debunked the attempt made in the previous post=
, but there could be some issues related to constructor deduction guides (i=
f constructors use class local concepts). This has to be investigated and i=
f issues are found there may have to be provisions in the standard text reg=
arding how to handle such situations.</div></div></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/dd36c1a5-70d6-41ef-95ae-dfd3ed000f33%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dd36c1a5-70d6-41ef-95ae-dfd3ed000f33=
%40isocpp.org</a>.<br />

------=_Part_1066_647505863.1534000727715--

------=_Part_1065_1054395461.1534000727714--

.


Author: florian.csdt@gmail.com
Date: Sat, 11 Aug 2018 08:26:29 -0700 (PDT)
Raw View
------=_Part_1086_1914637698.1534001189660
Content-Type: multipart/alternative;
 boundary="----=_Part_1087_1012918463.1534001189661"

------=_Part_1087_1012918463.1534001189661
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le samedi 11 ao=C3=BBt 2018 17:18:47 UTC+2, Nicol Bolas a =C3=A9crit :
>
> On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:
>>
>>
>>> That's an excellent reason to not permit this. Constraint normalization=
=20
>>> and subsumption checking operate on the concept's definition *before*=
=20
>>> instantiation, and so rely on a concept having a single unique definiti=
on.=20
>>> If you can have arbitrarily many definitions for what appears to be the=
=20
>>> same concept, how exactly do you normalize it and check for subsumption=
?
>>>
>>
>> I don't think this is a valid concern. A concept inside a class would=20
>> have to be accessed using Class<MyType>::theConcept, and in doing so the=
=20
>> actual template parameters are already known.
>> Obviously MyType can be a dependant type if the concept is used in=20
>> template code, but at the time of template instantiation the actual valu=
e=20
>> of MyType will be known anyway.
>>
>> As in my example above it seems reasonable to believe that the main use=
=20
>> of concepts in classes would be to specify characteristics of parameters=
 to=20
>> template functions in the same class. It does not seem important to defi=
ne=20
>> a concept in a class if it is not used as requirements in its own method=
s=20
>> or nested classes.=20
>>
>
>> Someone rasied the objection that we should not allow concepts in classe=
s=20
>> because we can't find a use case for it. I totally disagree with this id=
ea.=20
>> Finding interesting uses for a feature is a main driver for innovation. =
If=20
>> we didn't have SFINAE we might not have worked so hard to get concepts t=
o=20
>> get a better implementation of that type of overload selection.
>>
>
> I disagree with that. Without SFINAE, we would still have a genuine need=
=20
> for concepts. Indeed, without SFINAE, we would have more of a need, since=
=20
> we'd have to employ even more complex, expert-only ways of doing that kin=
d=20
> of stuff.
>
> If we had had variable templates from the beginning we would not have to=
=20
>> write _v on all our type traits now.=20
>>
> Template variables were excluded from C++98 because Bjarne didn't see any=
=20
>> use for them (he stated this in a private mail to me long time ago).
>>
>
> You've been using C++11 for too long. Bjarne was right; variable template=
s=20
> in C++98 were not useful.
>
> Variable templates are not useful by themselves; what makes them useful i=
s=20
> a combination of language features. Specifically, `constexpr` and `inline=
`=20
> variables. Without both of those features, you wouldn't really be able to=
=20
> replace type traits with variable templates. So we'd have still had to wa=
it=20
> until C++17.
>
> I get the general thrust of what you're saying. But my point is that all=
=20
> of those possible uses for class-scoped concepts are either minor=20
> conveniences (scoping the name) or things that should be done with *actua=
l=20
> features*, not hacks and kludges that manage to accomplish a useful=20
> effect. C++ is being updated with greater frequency now than in the C++98=
=20
> days. We don't need to allow everything on the assumption that someone=20
> might find a use for it. We can do "enough" and then expand next time if =
a=20
> genuine need emerges.
>

I would agree if allowing this would make the language more complicated.=20
Here, it is the opposite. It would make the language simpler as there would=
=20
be less corner cases.

Don't get me wrong, I'm not saying we should allow it. But I'm saying that=
=20
this argument doesn't really hold here (unless you can show that it would=
=20
be actually more complicated).
=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/fa758945-3bdd-423f-b7be-e8927cf8b9f5%40isocpp.or=
g.

------=_Part_1087_1012918463.1534001189661
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le samedi 11 ao=C3=BBt 2018 17:18:47 UTC+2, Nicol =
Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr">On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafs=
son wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>That&#=
39;s an excellent reason to not permit this. Constraint normalization and s=
ubsumption checking operate on the concept&#39;s definition *before* instan=
tiation, and so rely on a concept having a single unique definition. If you=
 can have arbitrarily many definitions for what appears to be the same conc=
ept, how exactly do you normalize it and check for subsumption?</div></div>=
</blockquote><div><br></div><div>I don&#39;t think this is a valid concern.=
 A concept inside a class would have to be accessed using Class&lt;MyType&g=
t;::theConcept, and in doing so the actual template parameters are already =
known.</div><div>Obviously MyType can be a dependant type if the concept is=
 used in template code, but at the time of template instantiation the actua=
l value of MyType will be known anyway.</div><div><br></div><div>As in my e=
xample above it seems reasonable to believe that the main use of concepts i=
n classes would be to specify characteristics of parameters to template fun=
ctions in the same class. It does not seem important to define a concept in=
 a class if it is not used as requirements in its own methods or nested cla=
sses. <br></div></div></blockquote><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div><br></div><div>Someone rasied the objection that we =
should not allow concepts in classes because we can&#39;t find a use case f=
or it. I totally disagree with this idea. Finding interesting uses for a fe=
ature is a main driver for innovation. If we didn&#39;t have SFINAE we migh=
t not have worked so hard to get concepts to get a better implementation of=
 that type of overload selection.</div></div></blockquote><div><br></div><d=
iv>I disagree with that. Without SFINAE, we would still have a genuine need=
 for concepts. Indeed, without SFINAE, we would have more of a need, since =
we&#39;d have to employ even more complex, expert-only ways of doing that k=
ind of stuff.<br></div><div><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div>If we had had variable templates from the beginnin=
g we would not have to write _v on all our type traits now. <br></div></div=
></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
>Template variables were excluded from C++98 because Bjarne didn&#39;t see =
any use for them (he stated this in a private mail to me long time ago).</d=
iv></div></blockquote><div><br></div><div>You&#39;ve been using C++11 for t=
oo long. Bjarne was right; variable templates in C++98 were not useful.</di=
v><div><br></div><div>Variable templates are not useful by themselves; what=
 makes them useful is a combination of language features. Specifically, `co=
nstexpr` and `inline` variables. Without both of those features, you wouldn=
&#39;t really be able to replace type traits with variable templates. So we=
&#39;d have still had to wait until C++17.</div><div><br></div><div>I get t=
he general thrust of what you&#39;re saying. But my point is that all of th=
ose possible uses for class-scoped concepts are either minor conveniences (=
scoping the name) or things that should be done with <i>actual features</i>=
, not hacks and kludges that manage to accomplish a useful effect. C++ is b=
eing updated with greater frequency now than in the C++98 days. We don&#39;=
t need to allow everything on the assumption that someone might find a use =
for it. We can do &quot;enough&quot; and then expand next time if a genuine=
 need emerges.</div></div></blockquote><div><br></div><div>I would agree if=
 allowing this would make the language more complicated. Here, it is the op=
posite. It would make the language simpler as there would be less corner ca=
ses.</div><div><br></div><div>Don&#39;t get me wrong, I&#39;m not saying we=
 should allow it. But I&#39;m saying that this argument doesn&#39;t really =
hold here (unless you can show that it would be actually more complicated).=
<br></div><div>=C2=A0</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/fa758945-3bdd-423f-b7be-e8927cf8b9f5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fa758945-3bdd-423f-b7be-e8927cf8b9f5=
%40isocpp.org</a>.<br />

------=_Part_1087_1012918463.1534001189661--

------=_Part_1086_1914637698.1534001189660--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sat, 11 Aug 2018 10:22:46 -0700
Raw View
--000000000000e9ec0705732c1b1d
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sat, Aug 11, 2018 at 7:39 AM, T. C. <rs2740@gmail.com> wrote:

> On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:
>>
>>
>>> That's an excellent reason to not permit this. Constraint normalization
>>> and subsumption checking operate on the concept's definition *before*
>>> instantiation, and so rely on a concept having a single unique definiti=
on.
>>> If you can have arbitrarily many definitions for what appears to be the
>>> same concept, how exactly do you normalize it and check for subsumption=
?
>>>
>> [...]
>>
>
> Assuming that X, Y, and Z are concepts,
>
> template<class T> struct C {
>     template<class U> concept Foo =3D X<U> && Y<U> && Z<U>;
> };
>
> template<> struct C<int> {
>     template<class U> concept Foo =3D X<U>;
> };
>
> template<class T>
>     requires C<T>::Foo<T>
> void f(T);   //#1
>
> template<class T>
>     requires X<T> && Y<T>
> void f(T);  // #2
>
> Your position is #1 is less constrained than #2 for some template
> parameters and more constrained for others?
>

My understanding is that yes, that would be the most natural conclusion.
We can manually create a similar situation today, not that anyone would
ever do this in practice...

https://wandbox.org/permlink/6hTA48vqHnPJehD0

template<size_t N> struct priority_tag : priority_tag<N-1> {};
template<> struct priority_tag<0> {};

// just for the sake of compilation; my understanding is that the
equivalent Concepts form a hierarchy already; that's not relevant here
template<class T> inline constexpr bool X =3D std::is_arithmetic_v<T>;
template<class T> inline constexpr bool Y =3D std::is_scalar_v<T>;
template<class T> inline constexpr bool Z =3D std::is_integral_v<T>;

template<class T> struct C {
    template<class U> static constexpr bool Foo =3D X<U> && Y<U> && Z<U>;
    using FooPriority =3D priority_tag<3>;
};

template<> struct C<int> {
    template<class U> static constexpr bool Foo =3D X<U>;
    using FooPriority =3D priority_tag<1>;
};

template<class T, class =3D std::enable_if_t<C<T>::Foo<T>>>
void f(C<T>::FooPriority, T);

template<class T, class =3D std::enable_if_t<X<T> && Y<T>>>
void f(priority_tag<2>, T);

int main() {
    f(priority_tag<99>{}, 42);  // calls the one constrained by C<T>::Foo
    f(priority_tag<99>{}, 42u);  // calls the one constrained by X && Y
}

(Notice that the manual approach clearly separates the "overload resolution
priority" feature (priority_tag) from the "constrain to drop out of
overload resolution entirely" feature (enable_if_t). Some people would say
that this is not only clearer but *cleaner*. The Concepts position, IIUC,
is that you so rarely want one without the other (or at least the other
never really hurts) that it makes sense to bundle them into a single
language feature.)


If Concepts permitted "dependent constraints" like the above, then, in
order to see which `f` should be called, the compiler would need to
actually instantiate `C<T>` =E2=80=94 it would not necessarily be able to
"short-circuit" the evaluation by observing that one of the `f`s has
constraints that are a superset of another's.

I'm not fully in the loop on Concepts; what's the reason that we don't want
the compiler to instantiate `C<T>` in Concepts (the exact same way it would
have done in my C++17 example above)?  Is it just to make the compiler more
efficient, or is there some fundamentally useful semantic effect that we
get from this "shortcut"?

A possibly analogous example is how the compiler eagerly substitutes in the
lexical expansions of type aliases, so that
template<class U> using W =3D X<U, A>;
template<class T> void foo(W<T>);
is treated as 100% identical to
template<class T> void foo(X<T, A>);
for template-parameter-deduction purposes. This is actually supremely
important, because if we didn't have this eager substitution, then many
parts of the STL would break. So I'm asking if there's a similar "killer
app" for Concepts' delaying the instantiation of things in require-clauses.

=E2=80=93Arthur

--=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/CADvuK0LVYB29nrXdqt85uHsTf3MnzZck8pVZr3pTWtc0ABB=
N8A%40mail.gmail.com.

--000000000000e9ec0705732c1b1d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sat, Aug 11, 2018 at 7:39 AM, T. C. <span dir=3D"ltr">&=
lt;<a href=3D"mailto:rs2740@gmail.com" target=3D"_blank">rs2740@gmail.com</=
a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quot=
e"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr"><span class=3D"gmail-">On Saturday, Au=
gust 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:r=
gb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>That=
&#39;s an excellent reason to not permit this. Constraint normalization and=
 subsumption checking operate on the concept&#39;s definition *before* inst=
antiation, and so rely on a concept having a single unique definition. If y=
ou can have arbitrarily many definitions for what appears to be the same co=
ncept, how exactly do you normalize it and check for subsumption?</div></di=
v></blockquote><div>[...]</div></div></blockquote><div><br></div></span><di=
v>Assuming that X, Y, and Z are concepts,</div><div><br></div><div>template=
&lt;class T&gt; struct C {</div><div>=C2=A0 =C2=A0 template&lt;class U&gt; =
concept Foo =3D X&lt;U&gt; &amp;&amp; Y&lt;U&gt; &amp;&amp; Z&lt;U&gt;;</di=
v><div>};</div><div><br></div><div>template&lt;&gt; struct C&lt;int&gt; {</=
div><div>=C2=A0 =C2=A0 template&lt;class U&gt; concept Foo =3D X&lt;U&gt;;<=
/div><div>};</div><div><br></div><div>template&lt;class T&gt;</div><div>=C2=
=A0 =C2=A0 requires C&lt;T&gt;::Foo&lt;T&gt;</div><div>void f(T);=C2=A0 =C2=
=A0//#1</div><div><br></div><div>template&lt;class T&gt;</div><div>=C2=A0 =
=C2=A0 requires X&lt;T&gt; &amp;&amp; Y&lt;T&gt;</div><div>void f(T);=C2=A0=
 // #2</div><div><br></div><div>Your position is #1 is less constrained tha=
n #2 for some template parameters and more constrained for others?</div></d=
iv></blockquote><div><br></div><div>My understanding is that yes, that woul=
d be the most natural conclusion.</div></div>We can manually create a simil=
ar situation today, not that anyone would ever do this in practice...</div>=
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><a href=3D"=
https://wandbox.org/permlink/6hTA48vqHnPJehD0">https://wandbox.org/permlink=
/6hTA48vqHnPJehD0</a><br></div><div class=3D"gmail_extra"><br></div><div cl=
ass=3D"gmail_extra">template&lt;size_t N&gt; struct priority_tag : priority=
_tag&lt;N-1&gt; {};</div><div class=3D"gmail_extra">template&lt;&gt; struct=
 priority_tag&lt;0&gt; {};</div><div class=3D"gmail_extra"><br></div><div c=
lass=3D"gmail_extra">// just for the sake of compilation; my understanding =
is that the equivalent Concepts form a hierarchy already; that&#39;s not re=
levant here</div><div class=3D"gmail_extra">template&lt;class T&gt; inline =
constexpr bool X =3D std::is_arithmetic_v&lt;T&gt;;</div><div class=3D"gmai=
l_extra"><div class=3D"gmail_extra">template&lt;class T&gt; inline constexp=
r bool Y =3D std::is_scalar_v&lt;T&gt;;</div><div><div class=3D"gmail_extra=
">template&lt;class T&gt; inline constexpr bool Z =3D std::is_integral_v&lt=
;T&gt;;</div></div><div><br></div></div><div class=3D"gmail_extra">template=
&lt;class T&gt; struct C {</div><div class=3D"gmail_extra">=C2=A0 =C2=A0 te=
mplate&lt;class U&gt; static constexpr bool Foo =3D X&lt;U&gt; &amp;&amp; Y=
&lt;U&gt; &amp;&amp; Z&lt;U&gt;;</div><div class=3D"gmail_extra">=C2=A0 =C2=
=A0 using FooPriority =3D priority_tag&lt;3&gt;;</div><div class=3D"gmail_e=
xtra">};</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extr=
a">template&lt;&gt; struct C&lt;int&gt; {</div><div class=3D"gmail_extra">=
=C2=A0 =C2=A0 template&lt;class U&gt; static constexpr bool Foo =3D X&lt;U&=
gt;;</div><div class=3D"gmail_extra">=C2=A0 =C2=A0 using FooPriority =3D pr=
iority_tag&lt;1&gt;;</div><div class=3D"gmail_extra">};</div><div class=3D"=
gmail_extra"><br></div><div class=3D"gmail_extra">template&lt;class T, clas=
s =3D std::enable_if_t&lt;C&lt;T&gt;::Foo&lt;T&gt;&gt;&gt;</div><div class=
=3D"gmail_extra">void f(C&lt;T&gt;::FooPriority, T);</div><div class=3D"gma=
il_extra"><br></div><div class=3D"gmail_extra"><div class=3D"gmail_extra">t=
emplate&lt;class T, class =3D std::enable_if_t&lt;X&lt;T&gt; &amp;&amp; Y&l=
t;T&gt;&gt;&gt;</div><div class=3D"gmail_extra">void f(priority_tag&lt;2&gt=
;, T);</div><div><br></div><div>int main() {</div><div>=C2=A0 =C2=A0 f(prio=
rity_tag&lt;99&gt;{}, 42); =C2=A0// calls the one constrained by C&lt;T&gt;=
::Foo<br></div><div>=C2=A0 =C2=A0 f(priority_tag&lt;99&gt;{}, 42u); =C2=A0/=
/ calls the one constrained by X &amp;&amp; Y<br></div><div>}</div><div><br=
></div><div>(Notice that the manual approach clearly separates the &quot;ov=
erload resolution priority&quot; feature (priority_tag) from the &quot;cons=
train to drop out of overload resolution entirely&quot; feature (enable_if_=
t). Some people would say that this is not only clearer but <i>cleaner</i>.=
 The Concepts position, IIUC, is that you so rarely want one without the ot=
her (or at least the other never really hurts) that it makes sense to bundl=
e them into a single language feature.)</div><div><br></div><div><br></div>=
<div>If Concepts permitted &quot;dependent constraints&quot; like the above=
, then, in order to see which `f` should be called, the compiler would need=
 to actually instantiate `C&lt;T&gt;` =E2=80=94 it would not necessarily be=
 able to &quot;short-circuit&quot; the evaluation by observing that one of =
the `f`s has constraints that are a superset of another&#39;s.</div><div><b=
r></div><div>I&#39;m not fully in the loop on Concepts; what&#39;s the reas=
on that we don&#39;t want the compiler to instantiate `C&lt;T&gt;` in Conce=
pts (the exact same way it would have done in my C++17 example above)?=C2=
=A0 Is it just to make the compiler more efficient, or is there some fundam=
entally useful semantic effect that we get from this &quot;shortcut&quot;?<=
/div><div><br></div><div>A possibly analogous example is how the compiler e=
agerly substitutes in the lexical expansions of type aliases, so that</div>=
<div>template&lt;class U&gt; using W =3D X&lt;U, A&gt;;</div><div>template&=
lt;class T&gt; void foo(W&lt;T&gt;);</div><div>is treated as 100% identical=
 to</div><div>template&lt;class T&gt; void foo(X&lt;T, A&gt;);</div><div>fo=
r template-parameter-deduction purposes. This is actually supremely importa=
nt, because if we didn&#39;t have this eager substitution, then many parts =
of the STL would break. So I&#39;m asking if there&#39;s a similar &quot;ki=
ller app&quot; for Concepts&#39; delaying the instantiation of things in re=
quire-clauses.</div><div><br></div><div>=E2=80=93Arthur</div></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/CADvuK0LVYB29nrXdqt85uHsTf3MnzZck8pVZ=
r3pTWtc0ABBN8A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0LVYB29nrXd=
qt85uHsTf3MnzZck8pVZr3pTWtc0ABBN8A%40mail.gmail.com</a>.<br />

--000000000000e9ec0705732c1b1d--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 11 Aug 2018 16:55:16 -0700 (PDT)
Raw View
------=_Part_1142_823279416.1534031716764
Content-Type: multipart/alternative;
 boundary="----=_Part_1143_1975935164.1534031716764"

------=_Part_1143_1975935164.1534031716764
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Den l=C3=B6rdag 11 augusti 2018 kl. 16:39:34 UTC+2 skrev T. C.:
>
>
>
> On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson wrote:
>>
>>
>>> That's an excellent reason to not permit this. Constraint normalization=
=20
>>> and subsumption checking operate on the concept's definition *before*=
=20
>>> instantiation, and so rely on a concept having a single unique definiti=
on.=20
>>> If you can have arbitrarily many definitions for what appears to be the=
=20
>>> same concept, how exactly do you normalize it and check for subsumption=
?
>>>
>>
>> I don't think this is a valid concern. A concept inside a class would=20
>> have to be accessed using Class<MyType>::theConcept, and in doing so the=
=20
>> actual template parameters are already known.
>> Obviously MyType can be a dependant type if the concept is used in=20
>> template code, but at the time of template instantiation the actual valu=
e=20
>> of MyType will be known anyway.
>>
>
> Assuming that X, Y, and Z are concepts,
>
> template<class T> struct C {
>     template<class U> concept Foo =3D X<U> && Y<U> && Z<U>;
> };
>
> template<> struct C<int> {
>     template<class U> concept Foo =3D X<U>;
> };
>
> template<class T>
>     requires C<T>::Foo<T>
> void f(T);   //#1
>
> template<class T>
>     requires X<T> && Y<T>
> void f(T);  // #2
>
> Your position is #1 is less constrained than #2 for some template=20
> parameters and more constrained for others?
>
Yes, that would be the case, and rather than this being a problem I suspect=
=20
that it could be useful.

The fact that to some extent C<T> has to be instantiated just to check if =
=20
C<T>::Foo<T> is valid for some T may be a reason for not allowing this: it=
=20
would be a bit strange that C<T> must be valid even for a T where the f=20
overload using the C<T>::Foo concept is not ultimately selected. To make=20
this idea more useful we would then have to allow some rule that concepts=
=20
can be tested without doing a full instantiation, or alternatively that any=
=20
error arising from attempting to instantiate C<T> would be a substitution=
=20
failure (i.e. not an error) but render all concepts in the template=20
instance evaluate to false. This however, does constitute a complication,=
=20
and thus could be a motivating reason for not allowing concepts in classes.

By the way: Note that in a class template declaration it actually makes=20
some sense to have non-template concepts, as the template parameters can be=
=20
used inside the concept's requirement clause. This makes some sense, for=20
instance containers could have a ValidElement<T> concept which is true for=
=20
Ts that can be used with the container. This would be differently defined=
=20
for different containers. In a function taking a container as a template=20
template parameter it would be beneficial to be able to test element=20
validity without knowing which container was passed!


--=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/05aef6eb-790b-44ab-a774-913c3982fdb8%40isocpp.or=
g.

------=_Part_1143_1975935164.1534031716764
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Den l=C3=B6rdag 11 augusti 2018 kl. 16:39:34 UTC+2=
 skrev T. C.:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<br><br>On Saturday, August 11, 2018 at 9:14:45 AM UTC-4, Bengt Gustafsson =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>That&#39;s=
 an excellent reason to not permit this. Constraint normalization and subsu=
mption checking operate on the concept&#39;s definition *before* instantiat=
ion, and so rely on a concept having a single unique definition. If you can=
 have arbitrarily many definitions for what appears to be the same concept,=
 how exactly do you normalize it and check for subsumption?</div></div></bl=
ockquote><div><br></div><div>I don&#39;t think this is a valid concern. A c=
oncept inside a class would have to be accessed using Class&lt;MyType&gt;::=
theConcept, and in doing so the actual template parameters are already know=
n.</div><div>Obviously MyType can be a dependant type if the concept is use=
d in template code, but at the time of template instantiation the actual va=
lue of MyType will be known anyway.</div></div></blockquote><div><br></div>=
<div>Assuming that X, Y, and Z are concepts,</div><div><br></div><div>templ=
ate&lt;class T&gt; struct C {</div><div>=C2=A0 =C2=A0 template&lt;class U&g=
t; concept Foo =3D X&lt;U&gt; &amp;&amp; Y&lt;U&gt; &amp;&amp; Z&lt;U&gt;;<=
/div><div>};</div><div><br></div><div>template&lt;&gt; struct C&lt;int&gt; =
{</div><div>=C2=A0 =C2=A0 template&lt;class U&gt; concept Foo =3D X&lt;U&gt=
;;</div><div>};</div><div><br></div><div>template&lt;class T&gt;</div><div>=
=C2=A0 =C2=A0 requires C&lt;T&gt;::Foo&lt;T&gt;</div><div>void f(T);=C2=A0 =
=C2=A0//#1</div><div><br></div><div>template&lt;class T&gt;</div><div>=C2=
=A0 =C2=A0 requires X&lt;T&gt; &amp;&amp; Y&lt;T&gt;</div><div>void f(T);=
=C2=A0 // #2</div><div><br></div><div>Your position is #1 is less constrain=
ed than #2 for some template parameters and more constrained for others?</d=
iv></div></blockquote><div>Yes, that would be the case, and rather than thi=
s being a problem I suspect that it could be useful.</div><div><br></div><d=
iv>The fact that to some extent C&lt;T&gt; has to be instantiated just to c=
heck if=C2=A0 C&lt;T&gt;::Foo&lt;T&gt; is valid for some T may be a reason =
for not allowing this: it would be a bit strange that C&lt;T&gt; must be va=
lid even for a T where the f overload using the C&lt;T&gt;::Foo concept is =
not ultimately selected. To make this idea more useful we would then have t=
o allow some rule that concepts can be tested without doing a full instanti=
ation, or alternatively that any error arising from attempting to instantia=
te C&lt;T&gt; would be a substitution failure (i.e. not an error) but rende=
r all concepts in the template instance evaluate to false. This however, do=
es constitute a complication, and thus could be a motivating reason for not=
 allowing concepts in classes.</div><div><br></div><div>By the way: Note th=
at in a class template declaration it actually makes some sense to have non=
-template concepts, as the template parameters can be used inside the conce=
pt&#39;s requirement clause. This makes some sense, for instance containers=
 could have a ValidElement&lt;T&gt; concept which is true for Ts that can b=
e used with the container. This would be differently defined for different =
containers. In a function taking a container as a template template paramet=
er it would be beneficial to be able to test element validity without knowi=
ng which container was passed!</div><div><br></div><div><br></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/05aef6eb-790b-44ab-a774-913c3982fdb8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/05aef6eb-790b-44ab-a774-913c3982fdb8=
%40isocpp.org</a>.<br />

------=_Part_1143_1975935164.1534031716764--

------=_Part_1142_823279416.1534031716764--

.