Topic: always_false meta-function class (was Re:
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 14 Aug 2016 11:34:12 +0200
Raw View
Le 11/08/2016 =C3=A0 01:13, Edward Catmur a =C3=A9crit :
> A non-type template parameter can't be NaN; floating point isn't allowed.
>
> I usually write something like static_assert(!std::conditional_t<true, st=
d::false_type, T>::value). Although might that be considered ill formed NDR=
on the basis that a conforming implementation could hard code std::conditi=
onal?
I'm interested in an answer with references to the standard.
>
> One needs something where a specialization conceivably could exist to mak=
e a predicate true, even though actually none do exist.
Yes, something more explicit like Matt's suggestion always_false should=20
work. IMO, generalizing always<T> to a type trait and a meta-function=20
class could be useful in the standard.
#include <type_traits>
template <class T>
struct always {
using type =3D T;
template <class U>
using apply =3D T;
};
template <class U>
using always_t =3D always<U>::type;
template <class U>
using always_false =3D always<std::false_type>::apply <U>;
template <class U>
using always_true =3D always<std::true_type>::apply <U>;
template <class T, bool B =3D true>
struct ex {};
template <class T>
struct ex<T, false> {
static_assert(!always_false<int>::value, "Error");
};
int main() {
ex<int> i;
}
Vicente
--=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/9423fcae-baf1-8262-c2de-cbd9a625f1e1%40wanadoo.f=
r.
.
Author: =?UTF-8?Q?=27Bernd_L=C3=B6rwald=27_via_ISO_C=2B=2B_Standard_=2D_Future_Proposal?=
Date: Sun, 14 Aug 2016 12:06:18 +0200
Raw View
> Am 14.08.2016 um 11:34 schrieb Vicente J. Botet Escriba <vicente.botet@wa=
nadoo.fr>:
>=20
> template <class U>
> using apply =3D T;
This should probably be `template<typename=E2=80=A6 U>` so that
template<typename=E2=80=A6 U>
using void_t =3D always_t<void>::apply<U=E2=80=A6>;
--=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/829944DD-6DE2-46D5-8663-9C4F0D4BF49E%40googlemai=
l.com.
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sun, 14 Aug 2016 12:39:23 -0700
Raw View
--001a1141136ed453a5053a0d451a
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sun, Aug 14, 2016 at 2:34 AM, Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr> wrote:
> Le 11/08/2016 =C3=A0 01:13, Edward Catmur a =C3=A9crit :
>>
>> A non-type template parameter can't be NaN; floating point isn't allowed=
..
>>
>> I usually write something like static_assert(!std::conditional_t<true,
>> std::false_type, T>::value). Although might that be considered ill forme=
d
>> NDR on the basis that a conforming implementation could hard code
>> std::conditional?
>
> I'm interested in an answer with references to the standard.
>>
>>
>> One needs something where a specialization conceivably could exist to
make
>> a predicate true, even though actually none do exist.
>
> Yes, something more explicit like Matt's suggestion always_false should
> work. IMO, generalizing always<T> to a type trait and a meta-function
class
> could be useful in the standard.
>
> #include <type_traits>
>
> template <class T>
> struct always {
> using type =3D T;
> template <class U>
> using apply =3D T;
> };
>
> template <class U>
> using always_t =3D always<U>::type;
>
> template <class U>
> using always_false =3D always<std::false_type>::apply <U>;
> template <class U>
> using always_true =3D always<std::true_type>::apply <U>;
My understanding is that if this were put into the STL, it would have
exactly the same drawback as std::conditional_t (for a sufficiently smart
compiler). The only thing saving you here is that always<T> is a class
template that might possibly be specialized for some type T in a different
translation unit, so the compiler has to(?) be conservative about its
diagnostics.
(? =E2=80=94 Richard Smith's post in this thread gave some competing defini=
tions of
"has to" based on different readings of the Standard; they range from "has
to even when you'd prefer otherwise" to "doesn't ever have to". Here
follows my own, more detailed but much less knowledgeable, explanation.)
I'm guessing that the wording in question is 14.6 [temp.res]/8:
> Knowing which names are type names allows the syntax of every template to
be checked. The program is
> ill-formed, no diagnostic required, if:
>
> (8.1) =E2=80=94 no valid specialization can be generated for a template o=
r a
substatement of a
> constexpr if statement (6.4.1) within a template and the template is not
instantiated, or
>
> (8.2) =E2=80=94 every valid specialization of a variadic template requir=
es an
empty template parameter pack, or
>
> (8.3) =E2=80=94 a hypothetical instantiation of a template immediately f=
ollowing
its definition would be ill-formed
> due to a construct that does not depend on a template parameter, or
>
> (8.4) =E2=80=94 the interpretation of such a construct in the hypothetica=
l
instantiation is different from the interpretation
> of the corresponding construct in any actual instantiation of the
template.
> [Note: This can happen in situations including the following:
> (8.4.1) =E2=80=94 a type used in a non-dependent name is incomplete =
at the
point at which a template is defined
> but is complete at the point at which an instantiation is performed,
or
> (8.4.2) =E2=80=94 an instantiation uses a default argument or defaul=
t
template argument that had not been defined
> at the point at which the template was defined, or
> (8.4.3) =E2=80=94 constant expression evaluation (5.20) within the t=
emplate
instantiation uses
> (8.4.3.1) =E2=80=94 the value of a const object of integral or un=
scoped
enumeration type or
> (8.4.3.2) =E2=80=94 the value of a constexpr object or
> (8.4.3.3) =E2=80=94 the value of a reference or
> (8.4.3.4) =E2=80=94 the definition of a constexpr function,
> and that entity was not defined when the template was defined, or
> (8.4.4) =E2=80=94 a class template specialization or variable templa=
te
specialization that is specified by a
> non-dependent simple-template-id is used by the template, and either
it is instantiated from a
> partial specialization that was not defined when the template was
defined or it names an
> explicit specialization that was not declared when the template was
defined.
> =E2=80=94 end note]
I believe that the difficulty with static_assert(false) right now is clause
(8.3) "a hypothetical instantiation of a template immediately following its
definition would be ill-formed due to a construct that does not depend on a
template parameter",
Clause (8.4) merely adds more stuff on top of "such a construct", i.e. "a
construct that does not depend on a template parameter", so (luckily for
us) it's only exactly as relevant as clause (8.3).
Clause (8.1) might also be relevant, depending on your interpretation of
the phrase "no valid specialization can be generated". Suppose template
A<T> is perfectly well-formed in its signature and so on, but merely
happens to contain static_assert(false_t<T>), so that any program that
instantiates A<int> will be ill-formed. Does this mean that A<int> is not
a "valid specialization" from the Standard's point of view? I grepped a
bit, but the term "valid specialization" doesn't seem to be defined
anywhere, at least not using that exact phrase.
Depending on your interpretation of (8.1), it might rule out all programs
containing uninstantiated templates, or no programs.
I have not found any language in the Standard (yet) that would draw a
distinction between false_t<T> and sizeof(T)=3D=3D0; both of those construc=
ts
are dependent (which is what I take 8.3's fuzzy "depend on a template
parameter" to mean), so they can only fall foul of (8.1) or of some other
rule I haven't found yet.
Tangentially, (8.2) struck me as odd, so I did some tests with Clang:
http://melpon.org/wandbox/permlink/mfaUyRwhXtaEaesS
The only case I could think of for (8.2) was if you used something like
A<int, T...> where A was a template taking only a single parameter. But
Clang actually rejects such constructs eagerly in many situations when
they'd intuitively be well-formed, so either there's some other rule
kicking in, or Clang has bugs in this area. See the above-linked test case=
..
=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/CADvuK0%2BOfcKgbMeooUSpR8GJPgb%3DLLG-zYaqfcFnqOh=
nv5bzEQ%40mail.gmail.com.
--001a1141136ed453a5053a0d451a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sun, Aug 14, 2016 at 2:34 AM, Vicente J. Botet Escriba =
<<a href=3D"mailto:vicente.botet@wanadoo.fr">vicente.botet@wanadoo.fr</a=
>> wrote:<br>> Le 11/08/2016 =C3=A0 01:13, Edward Catmur a =C3=A9crit=
:<br>>><br>>> A non-type template parameter can't be NaN; =
floating point isn't allowed.<br>>><br>>> I usually write s=
omething like static_assert(!std::conditional_t<true,<br>>> std::f=
alse_type, T>::value). Although might that be considered ill formed<br>&=
gt;> NDR on the basis that a conforming implementation could hard code<b=
r>>> std::conditional?<br>><br>> I'm interested in an answe=
r with references to the standard.<br>>><br>>><br>>> One =
needs something where a specialization conceivably could exist to make<br>&=
gt;> a predicate true, even though actually none do exist.<br>><br>&g=
t; Yes, something more explicit like Matt's suggestion always_false sho=
uld<br>> work. IMO, generalizing always<T> to a type trait and a m=
eta-function class<br>> could be useful in the standard.<br>><br>>=
#include <type_traits><br>><br>> template <class T><br>&=
gt; struct always {<br>> =C2=A0 =C2=A0 using type =3D T;<br>> =C2=A0 =
=C2=A0 template <class U><br>> =C2=A0 =C2=A0 using apply =3D T;<br=
>> };<br>><br>> template <class U><br>> using always_t =
=3D always<U>::type;<br>><br>> template <class U><br>>=
using always_false =3D always<std::false_type>::apply <U>;<br>=
> template <class U><br>> using always_true =3D always<std::=
true_type>::apply <U>;<br><br>My understanding is that if this wer=
e put into the STL, it would have exactly the same drawback as std::conditi=
onal_t (for a sufficiently smart compiler). The only thing saving you here =
is that always<T> is a class template that might possibly be speciali=
zed for some type T in a different translation unit, so the compiler has to=
(?) be conservative about its diagnostics.<br>(? =E2=80=94 Richard Smith=
9;s post in this thread gave some competing definitions of "has to&quo=
t; based on different readings of the Standard; they range from "has t=
o even when you'd prefer otherwise" to "doesn't ever have=
to".=C2=A0 Here follows my own, more detailed but much less knowledge=
able, explanation.)<br><br>I'm guessing that the wording in question is=
14.6 [temp.res]/8:<br><br>> Knowing which names are type names allows t=
he syntax of every template to be checked. The program is<br>> ill-forme=
d, no diagnostic required, if:<br>><br>> (8.1) =E2=80=94 no valid spe=
cialization can be generated for a template or a substatement of a<br>> =
constexpr if statement (6.4.1) within a template and the template is not in=
stantiated, or<br>><br>> (8.2) =E2=80=94 =C2=A0every valid specializa=
tion of a variadic template requires an empty template parameter pack, or<b=
r>><br>> (8.3) =E2=80=94 =C2=A0a hypothetical instantiation of a temp=
late immediately following its definition would be ill-formed<br>> due t=
o a construct that does not depend on a template parameter, or<br>><br>&=
gt; (8.4) =E2=80=94 the interpretation of such a construct in the hypotheti=
cal instantiation is different from the interpretation<br>> of the corre=
sponding construct in any actual instantiation of the template.<br>> =C2=
=A0 =C2=A0 [Note: This can happen in situations including the following:<br=
>> =C2=A0 =C2=A0 (8.4.1) =E2=80=94 =C2=A0a type used in a non-dependent =
name is incomplete at the point at which a template is defined<br>> =C2=
=A0 =C2=A0 but is complete at the point at which an instantiation is perfor=
med, or<br>> =C2=A0 =C2=A0 (8.4.2) =E2=80=94 =C2=A0an instantiation uses=
a default argument or default template argument that had not been defined<=
br>> =C2=A0 =C2=A0 at the point at which the template was defined, or<br=
>> =C2=A0 =C2=A0 (8.4.3) =E2=80=94 =C2=A0constant expression evaluation =
(5.20) within the template instantiation uses<br>> =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 (8.4.3.1) =E2=80=94 the value of a const object of integral or unsco=
ped enumeration type or<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (8.4.3.2) =E2=
=80=94 the value of a constexpr object or<br>> =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (8.4.3.3) =E2=80=94 the value of a reference or<br>> =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 (8.4.3.4) =E2=80=94 the definition of a constexpr function,<b=
r>> =C2=A0 =C2=A0 and that entity was not defined when the template was =
defined, or<br>> =C2=A0 =C2=A0 (8.4.4) =E2=80=94 =C2=A0a class template =
specialization or variable template specialization that is specified by a<b=
r>> =C2=A0 =C2=A0 non-dependent simple-template-id is used by the templa=
te, and either it is instantiated from a<br>> =C2=A0 =C2=A0 partial spec=
ialization that was not defined when the template was defined or it names a=
n<br>> =C2=A0 =C2=A0 explicit specialization that was not declared when =
the template was defined.<br>> =E2=80=94 end note]<br><br><br>I believe =
that the difficulty with static_assert(false) right now is clause (8.3) &qu=
ot;a hypothetical instantiation of a template immediately following its def=
inition would be ill-formed due to a construct that does not depend on a te=
mplate parameter",<br><br>Clause (8.4) merely adds more stuff on top o=
f "such a construct", i.e. "a construct that does not depend=
on a template parameter", so (luckily for us) it's only exactly a=
s relevant as clause (8.3).<br><br>Clause (8.1) might also be relevant, dep=
ending on your interpretation of the phrase "no valid specialization c=
an be generated".=C2=A0 Suppose template A<T> is perfectly well-=
formed in its signature and so on, but merely happens to contain static_ass=
ert(false_t<T>), so that any program that instantiates A<int> w=
ill be ill-formed. Does this mean that A<int> is not<br>a "valid=
specialization" from the Standard's point of view?=C2=A0 I greppe=
d a bit, but the term "valid specialization" doesn't seem to =
be defined anywhere, at least not using that exact phrase.<div>Depending on=
your interpretation of (8.1), it might rule out all programs containing un=
instantiated templates, or no programs.<br><div><br></div><div>I have not f=
ound any language in the Standard (yet) that would draw a distinction betwe=
en false_t<T> and sizeof(T)=3D=3D0; both of those constructs are depe=
ndent (which is what I take 8.3's fuzzy "depend on a template para=
meter" to mean), so they can only fall foul of (8.1) or of some other =
rule I haven't found yet.</div><div><br></div><div><br></div><div>Tange=
ntially, (8.2) struck me as odd, so I did some tests with Clang:<br><a href=
=3D"http://melpon.org/wandbox/permlink/mfaUyRwhXtaEaesS">http://melpon.org/=
wandbox/permlink/mfaUyRwhXtaEaesS</a></div><div>The only case I could think=
of for (8.2) was if you used something like A<int, T...> where A was=
a template taking only a single parameter. But Clang actually rejects such=
constructs eagerly in many situations when they'd intuitively be well-=
formed, so either there's some other rule kicking in, or Clang has bugs=
in this area.=C2=A0 See the above-linked test case.</div><div><br></div><d=
iv>=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" 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/CADvuK0%2BOfcKgbMeooUSpR8GJPgb%3DLLG-=
zYaqfcFnqOhnv5bzEQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BOfc=
KgbMeooUSpR8GJPgb%3DLLG-zYaqfcFnqOhnv5bzEQ%40mail.gmail.com</a>.<br />
--001a1141136ed453a5053a0d451a--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 14 Aug 2016 23:26:51 +0200
Raw View
This is a multi-part message in MIME format.
--------------5144559D16E01A3944EB4F3A
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 14/08/2016 =C3=A0 12:06, 'Bernd L=C3=B6rwald' via ISO C++ Standard - Fut=
ure=20
Proposals a =C3=A9crit :
>> Am 14.08.2016 um 11:34 schrieb Vicente J. Botet Escriba <vicente.botet@w=
anadoo.fr>:
>>
>> template <class U>
>> using apply =3D T;
> This should probably be `template<typename=E2=80=A6 U>` so that
>
> template<typename=E2=80=A6 U>
> using void_t =3D always_t<void>::apply<U=E2=80=A6>;
>
Right.
Vicente
--=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/67a97a56-da86-45d5-cf6a-86a28c57412e%40wanadoo.f=
r.
--------------5144559D16E01A3944EB4F3A
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 14/08/2016 =C3=A0 12:06, 'Bernd L=C3=
=B6rwald'
via ISO C++ Standard - Future Proposals a =C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:829944DD-6DE2-46D5-8663-9C4F0D4BF49E@googlemail.com"
type=3D"cite">
<pre wrap=3D"">
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">Am 14.08.2016 um 11:34 schrieb Vicente J. Botet Escr=
iba <a class=3D"moz-txt-link-rfc2396E" href=3D"mailto:vicente.botet@wanadoo=
..fr"><vicente.botet@wanadoo.fr></a>:
template <class U>
using apply =3D T;
</pre>
</blockquote>
<pre wrap=3D"">
This should probably be `template<typename=E2=80=A6 U>` so that
template<typename=E2=80=A6 U>
using void_t =3D always_t<void>::apply<U=E2=80=A6>;
</pre>
</blockquote>
<p><font size=3D"+1">Right.</font></p>
<p><font size=3D"+1">Vicente</font><br>
</p>
</body>
</html>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/67a97a56-da86-45d5-cf6a-86a28c57412e%=
40wanadoo.fr?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/67a97a56-da86-45d5-cf6a-86a28c57412e=
%40wanadoo.fr</a>.<br />
--------------5144559D16E01A3944EB4F3A--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 15 Aug 2016 12:45:28 -0700
Raw View
--001a114798b2744a63053a21795a
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sun, Aug 14, 2016 at 12:39 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com=
>
wrote:
> On Sun, Aug 14, 2016 at 2:34 AM, Vicente J. Botet Escriba <
> vicente.botet@wanadoo.fr> wrote:
> > Le 11/08/2016 =C3=A0 01:13, Edward Catmur a =C3=A9crit :
> >>
> >> A non-type template parameter can't be NaN; floating point isn't
> allowed.
> >>
> >> I usually write something like static_assert(!std::conditional_t<true,
> >> std::false_type, T>::value). Although might that be considered ill
> formed
> >> NDR on the basis that a conforming implementation could hard code
> >> std::conditional?
> >
> > I'm interested in an answer with references to the standard.
> >>
> >>
> >> One needs something where a specialization conceivably could exist to
> make
> >> a predicate true, even though actually none do exist.
> >
> > Yes, something more explicit like Matt's suggestion always_false should
> > work. IMO, generalizing always<T> to a type trait and a meta-function
> class
> > could be useful in the standard.
> >
> > #include <type_traits>
> >
> > template <class T>
> > struct always {
> > using type =3D T;
> > template <class U>
> > using apply =3D T;
> > };
> >
> > template <class U>
> > using always_t =3D always<U>::type;
> >
> > template <class U>
> > using always_false =3D always<std::false_type>::apply <U>;
> > template <class U>
> > using always_true =3D always<std::true_type>::apply <U>;
>
> My understanding is that if this were put into the STL, it would have
> exactly the same drawback as std::conditional_t (for a sufficiently smart
> compiler). The only thing saving you here is that always<T> is a class
> template that might possibly be specialized for some type T in a differen=
t
> translation unit, so the compiler has to(?) be conservative about its
> diagnostics.
> (? =E2=80=94 Richard Smith's post in this thread gave some competing defi=
nitions
> of "has to" based on different readings of the Standard; they range from
> "has to even when you'd prefer otherwise" to "doesn't ever have to". Her=
e
> follows my own, more detailed but much less knowledgeable, explanation.)
>
> I'm guessing that the wording in question is 14.6 [temp.res]/8:
>
> > Knowing which names are type names allows the syntax of every template
> to be checked. The program is
> > ill-formed, no diagnostic required, if:
> >
> > (8.1) =E2=80=94 no valid specialization can be generated for a template=
or a
> substatement of a
> > constexpr if statement (6.4.1) within a template and the template is no=
t
> instantiated, or
> >
> > (8.2) =E2=80=94 every valid specialization of a variadic template requ=
ires an
> empty template parameter pack, or
> >
> > (8.3) =E2=80=94 a hypothetical instantiation of a template immediately
> following its definition would be ill-formed
> > due to a construct that does not depend on a template parameter, or
> >
> > (8.4) =E2=80=94 the interpretation of such a construct in the hypotheti=
cal
> instantiation is different from the interpretation
> > of the corresponding construct in any actual instantiation of the
> template.
> > [Note: This can happen in situations including the following:
> > (8.4.1) =E2=80=94 a type used in a non-dependent name is incomplet=
e at the
> point at which a template is defined
> > but is complete at the point at which an instantiation is performed=
,
> or
> > (8.4.2) =E2=80=94 an instantiation uses a default argument or defa=
ult
> template argument that had not been defined
> > at the point at which the template was defined, or
> > (8.4.3) =E2=80=94 constant expression evaluation (5.20) within the=
template
> instantiation uses
> > (8.4.3.1) =E2=80=94 the value of a const object of integral or =
unscoped
> enumeration type or
> > (8.4.3.2) =E2=80=94 the value of a constexpr object or
> > (8.4.3.3) =E2=80=94 the value of a reference or
> > (8.4.3.4) =E2=80=94 the definition of a constexpr function,
> > and that entity was not defined when the template was defined, or
> > (8.4.4) =E2=80=94 a class template specialization or variable temp=
late
> specialization that is specified by a
> > non-dependent simple-template-id is used by the template, and eithe=
r
> it is instantiated from a
> > partial specialization that was not defined when the template was
> defined or it names an
> > explicit specialization that was not declared when the template was
> defined.
> > =E2=80=94 end note]
>
>
> I believe that the difficulty with static_assert(false) right now is
> clause (8.3) "a hypothetical instantiation of a template immediately
> following its definition would be ill-formed due to a construct that does
> not depend on a template parameter",
>
> Clause (8.4) merely adds more stuff on top of "such a construct", i.e. "a
> construct that does not depend on a template parameter", so (luckily for
> us) it's only exactly as relevant as clause (8.3).
>
> Clause (8.1) might also be relevant, depending on your interpretation of
> the phrase "no valid specialization can be generated". Suppose template
> A<T> is perfectly well-formed in its signature and so on, but merely
> happens to contain static_assert(false_t<T>), so that any program that
> instantiates A<int> will be ill-formed. Does this mean that A<int> is not
> a "valid specialization" from the Standard's point of view? I grepped a
> bit, but the term "valid specialization" doesn't seem to be defined
> anywhere, at least not using that exact phrase.
> Depending on your interpretation of (8.1), it might rule out all programs
> containing uninstantiated templates, or no programs.
>
> I have not found any language in the Standard (yet) that would draw a
> distinction between false_t<T> and sizeof(T)=3D=3D0; both of those constr=
ucts
> are dependent (which is what I take 8.3's fuzzy "depend on a template
> parameter" to mean), so they can only fall foul of (8.1) or of some other
> rule I haven't found yet.
>
>
> Tangentially, (8.2) struck me as odd, so I did some tests with Clang:
> http://melpon.org/wandbox/permlink/mfaUyRwhXtaEaesS
> The only case I could think of for (8.2) was if you used something like
> A<int, T...> where A was a template taking only a single parameter. But
> Clang actually rejects such constructs eagerly in many situations when
> they'd intuitively be well-formed, so either there's some other rule
> kicking in, or Clang has bugs in this area. See the above-linked test ca=
se.
>
Bullet 8.2 above allows Clang to reject such cases.There are lots of other
ways in which it applies, for instance:
template<typename ...T> union U : T... {};
template<size_t ...N> void f() { int a(5, N...); }
template<void *...P> void g() { int a[] =3D {P...}; }
struct X;
template<typename ...T> void h() { int a[] =3D { X::foo(T())... }; }
--=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/CAOfiQqnNDCMzaN47qgmO4qxhV533Eoa5e8doM5R%3DWL%3D=
2XVKNRg%40mail.gmail.com.
--001a114798b2744a63053a21795a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Aug 14, 2016 at 12:39 PM, Arthur O'Dwyer <span dir=3D"ltr"><<a h=
ref=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@=
gmail.com</a>></span> wrote:<br><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 class=3D"h5">On Sun, Aug 14, 2016 at 2:34 AM, Vicente J.=
Botet Escriba <<a href=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_b=
lank">vicente.botet@wanadoo.fr</a>> wrote:<br>> Le 11/08/2016 =C3=A0 =
01:13, Edward Catmur a =C3=A9crit :<br>>><br>>> A non-type temp=
late parameter can't be NaN; floating point isn't allowed.<br>>&=
gt;<br>>> I usually write something like static_assert(!std::<wbr>con=
ditional_t<true,<br>>> std::false_type, T>::value). Although mi=
ght that be considered ill formed<br>>> NDR on the basis that a confo=
rming implementation could hard code<br>>> std::conditional?<br>><=
br>> I'm interested in an answer with references to the standard.<br=
>>><br>>><br>>> One needs something where a specializatio=
n conceivably could exist to make<br>>> a predicate true, even though=
actually none do exist.<br>><br>> Yes, something more explicit like =
Matt's suggestion always_false should<br>> work. IMO, generalizing a=
lways<T> to a type trait and a meta-function class<br>> could be u=
seful in the standard.<br>><br>> #include <type_traits><br>>=
<br>> template <class T><br>> struct always {<br>> =C2=A0 =
=C2=A0 using type =3D T;<br>> =C2=A0 =C2=A0 template <class U><br>=
> =C2=A0 =C2=A0 using apply =3D T;<br>> };<br>><br>> template &=
lt;class U><br>> using always_t =3D always<U>::type;<br>><br=
>> template <class U><br>> using always_false =3D always<std=
::false_type>::apply <U>;<br>> template <class U><br>>=
using always_true =3D always<std::true_type>::apply <U>;<br><b=
r></div></div>My understanding is that if this were put into the STL, it wo=
uld have exactly the same drawback as std::conditional_t (for a sufficientl=
y smart compiler). The only thing saving you here is that always<T> i=
s a class template that might possibly be specialized for some type T in a =
different translation unit, so the compiler has to(?) be conservative about=
its diagnostics.<br>(? =E2=80=94 Richard Smith's post in this thread g=
ave some competing definitions of "has to" based on different rea=
dings of the Standard; they range from "has to even when you'd pre=
fer otherwise" to "doesn't ever have to".=C2=A0 Here fol=
lows my own, more detailed but much less knowledgeable, explanation.)<br><b=
r>I'm guessing that the wording in question is 14.6 [temp.res]/8:<br><b=
r>> Knowing which names are type names allows the syntax of every templa=
te to be checked. The program is<br>> ill-formed, no diagnostic required=
, if:<br>><br>> (8.1) =E2=80=94 no valid specialization can be genera=
ted for a template or a substatement of a<br>> constexpr if statement (6=
..4.1) within a template and the template is not instantiated, or<br>><br=
>> (8.2) =E2=80=94 =C2=A0every valid specialization of a variadic templa=
te requires an empty template parameter pack, or<br>><br>> (8.3) =E2=
=80=94 =C2=A0a hypothetical instantiation of a template immediately followi=
ng its definition would be ill-formed<br>> due to a construct that does =
not depend on a template parameter, or<br>><br>> (8.4) =E2=80=94 the =
interpretation of such a construct in the hypothetical instantiation is dif=
ferent from the interpretation<br>> of the corresponding construct in an=
y actual instantiation of the template.<br>> =C2=A0 =C2=A0 [Note: This c=
an happen in situations including the following:<br>> =C2=A0 =C2=A0 (8.4=
..1) =E2=80=94 =C2=A0a type used in a non-dependent name is incomplete at th=
e point at which a template is defined<br>> =C2=A0 =C2=A0 but is complet=
e at the point at which an instantiation is performed, or<br>> =C2=A0 =
=C2=A0 (8.4.2) =E2=80=94 =C2=A0an instantiation uses a default argument or =
default template argument that had not been defined<br>> =C2=A0 =C2=A0 a=
t the point at which the template was defined, or<br>> =C2=A0 =C2=A0 (8.=
4.3) =E2=80=94 =C2=A0constant expression evaluation (5.20) within the templ=
ate instantiation uses<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (8.4.3.1) =E2=80=
=94 the value of a const object of integral or unscoped enumeration type or=
<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (8.4.3.2) =E2=80=94 the value of a con=
stexpr object or<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (8.4.3.3) =E2=80=94 th=
e value of a reference or<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 (8.4.3.4) =E2=
=80=94 the definition of a constexpr function,<br>> =C2=A0 =C2=A0 and th=
at entity was not defined when the template was defined, or<br>> =C2=A0 =
=C2=A0 (8.4.4) =E2=80=94 =C2=A0a class template specialization or variable =
template specialization that is specified by a<br>> =C2=A0 =C2=A0 non-de=
pendent simple-template-id is used by the template, and either it is instan=
tiated from a<br>> =C2=A0 =C2=A0 partial specialization that was not def=
ined when the template was defined or it names an<br>> =C2=A0 =C2=A0 exp=
licit specialization that was not declared when the template was defined.<b=
r>> =E2=80=94 end note]<br><br><br>I believe that the difficulty with st=
atic_assert(false) right now is clause (8.3) "a hypothetical instantia=
tion of a template immediately following its definition would be ill-formed=
due to a construct that does not depend on a template parameter",<br>=
<br>Clause (8.4) merely adds more stuff on top of "such a construct&qu=
ot;, i.e. "a construct that does not depend on a template parameter&qu=
ot;, so (luckily for us) it's only exactly as relevant as clause (8.3).=
<br><br>Clause (8.1) might also be relevant, depending on your interpretati=
on of the phrase "no valid specialization can be generated".=C2=
=A0 Suppose template A<T> is perfectly well-formed in its signature a=
nd so on, but merely happens to contain static_assert(false_t<T>), so=
that any program that instantiates A<int> will be ill-formed. Does t=
his mean that A<int> is not<br>a "valid specialization" fro=
m the Standard's point of view?=C2=A0 I grepped a bit, but the term &qu=
ot;valid specialization" doesn't seem to be defined anywhere, at l=
east not using that exact phrase.<div>Depending on your interpretation of (=
8.1), it might rule out all programs containing uninstantiated templates, o=
r no programs.<br><div><br></div><div>I have not found any language in the =
Standard (yet) that would draw a distinction between false_t<T> and s=
izeof(T)=3D=3D0; both of those constructs are dependent (which is what I ta=
ke 8.3's fuzzy "depend on a template parameter" to mean), so =
they can only fall foul of (8.1) or of some other rule I haven't found =
yet.</div><div><br></div><div><br></div><div>Tangentially, (8.2) struck me =
as odd, so I did some tests with Clang:<br><a href=3D"http://melpon.org/wan=
dbox/permlink/mfaUyRwhXtaEaesS" target=3D"_blank">http://melpon.org/wandbox=
/<wbr>permlink/mfaUyRwhXtaEaesS</a></div><div>The only case I could think o=
f for (8.2) was if you used something like A<int, T...> where A was a=
template taking only a single parameter. But Clang actually rejects such c=
onstructs eagerly in many situations when they'd intuitively be well-fo=
rmed, so either there's some other rule kicking in, or Clang has bugs i=
n this area.=C2=A0 See the above-linked test case.</div></div></div></block=
quote><div><br></div><div>Bullet 8.2 above allows Clang to reject such case=
s.There are lots of other ways in which it applies, for instance:</div><div=
><br></div><div>template<typename ...T> union U : T... {};</div><div>=
template<size_t ...N> void f() { int a(5, N...); }</div><div>template=
<void *...P> void g() { int a[] =3D {P...}; }</div><div>struct X;</di=
v><div>template<typename ...T> void h() { int a[] =3D { X::foo(T())..=
.. }; }</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAOfiQqnNDCMzaN47qgmO4qxhV533Eoa5e8do=
M5R%3DWL%3D2XVKNRg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnNDCMz=
aN47qgmO4qxhV533Eoa5e8doM5R%3DWL%3D2XVKNRg%40mail.gmail.com</a>.<br />
--001a114798b2744a63053a21795a--
.