Topic: A SFINAE-friendly typedef member for
Author: Nicolas Lesser <blitzrakete@gmail.com>
Date: Mon, 2 Jul 2018 12:00:05 +0200
Raw View
--000000000000b21106057001436f
Content-Type: text/plain; charset="UTF-8"
If I understand you correctly, you want your proposal because it enables
you to avoid using std::enable_if why using that type as the return type. I
don't find this reason compelling enough.
Your first usage example can be rewritten to
template <class T>
requires is_arithmetic_v<T>
void arith_ok(T t) { cout << "T is an arithmetic type\n"; }
which is IMO much clearer. Same goes for the variadic case with a fold
expression.
On Mon, Jul 2, 2018, 10:39 AM Paul Keir <graham.keir@gmail.com> wrote:
> In summary I propose the addition of a SFINAE-friendly typedef member type
> sfinae_type, assigned to void, to all of the boolean predicate type
> traits in the standard library.
>
> Type traits corresponding to binary predicates give their boolean result
> in different ways. Most commonly, the instantiated type will contain a
> constant data member named value which is equal either to true or false.
> This idiom can be observed in most type traits; such as std::is_void,
> std::is_fundamental or std::is_const. For example:
>
> static_assert(true == is_same<char,char>::value);
> static_assert(false == is_volatile<char>::value);
>
> For other type traits, the result is a member typedef type. For example,
> std::add_pointer or std::decay. Furthermore, the type member result of
> some such traits, may or may not exist. Consequently the presence, or
> absence, of a typedef member within the instantiated type can correlate
> with true or false respectively. std::common_type, std::iterator_traits
> and std::result_of execute this approach. For example:
>
> iterator_traits<vector<int>::iterator>::difference_type diff_t;
> common_type<int,int*>::type ct_t; // error
> result_of<plus<int>(int,char*)>::type ro_t; // error
>
> The latter approach can be described as SFINAE-friendly, in that a
> non-existent trait result will not produce an error when involved in an
> invalid substitution of template parameters. For example, consider the use
> of std::common_type_t in the definition of the overloaded binary subtract
> operator for std::duration. Shown below, this function will not be
> instantiated when there is insufficient commonality between the types of
> its two arguments:
>
> template <class Rep1, class Period1, class Rep2, class Period2>
> common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
> constexpr operator-( const duration<Rep1, Period1>& lhs
> , const duration<Rep2, Period2>& rhs
> );
>
> We propose that a SFINAE-friendly member typedef type named sfinae_type
> assigned to void be added to all binary predicate type traits. For example,
> whereas std::is_same<char,int>::sfinae_type would not be a valid name;
> std::is_scalar<int>::sfinae_type would be. Consequently, a function valid
> only for arguments of arithmetic type could be written:
>
> template <class T>
> typename is_arithmetic<T>::sfinae_type
> arith_ok(T t) { cout << "T is an arithmetic type\n"; }
>
> The useful C++17 type trait std::void_t then allows a conjunction of
> standard traits:
>
> template<typename T, typename... Ts>
> void_t<typename is_same<T, Ts>::sfinae_type...>
> func(T, Ts...) { cout << "all types in pack are T\n"; }
>
> Type traits such as std::enable_if and std::void_t facilitate further
> composition of predicates in the construction of SFINAE type expressions.
> The sfinae_type member would also be added to the C++17 traits
> std::conjunction, std::disjunction, and std::negate. Consequently, a
> function which is valid for arguments of arithmetic type, but not types
> which are an std::nullptr_t or an enumeration type could look as follows:
>
> template <class T>
> typename conjunction<
> is_scalar<T>,
> negation< disjunction< is_null_pointer<T>, is_enum<T> > >
> >::sfinae_type
> arith_ptr_or_memptr(T) { cout << "arithmetic, ptr, or member ptr\n"; }
>
> Sample code is available at https://wandbox.org/permlink/o0fIFssB6Gl6oRKS.
> The code uses the mk_sfinae helper to construct a trait from an existing
> trait and its template arguments.
>
> Feedback is most welcome.
>
> --
> 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/17994533-9542-4403-b447-963cb85d29e6%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/17994533-9542-4403-b447-963cb85d29e6%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/CALmDwq14yUxEfAiFF%2B1m0qtM%2BugAoxNuM%3D4wWDK6o6ZhG5%2BtcA%40mail.gmail.com.
--000000000000b21106057001436f
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div>If I understand you correctly, you want your proposa=
l because it enables you to avoid using std::enable_if why using that type =
as the return type. I don't find this reason compelling enough.</div><d=
iv dir=3D"auto"><div dir=3D"auto"><br></div><div dir=3D"auto">Your first us=
age example can be rewritten to</div><div dir=3D"auto"><br></div><div dir=
=3D"auto"><span style=3D"font-family:monospace;background-color:rgb(250,250=
,250);color:rgb(0,0,136)">template</span><span style=3D"font-family:monospa=
ce;background-color:rgb(250,250,250)">=C2=A0</span><span style=3D"font-fami=
ly:monospace;background-color:rgb(250,250,250);color:rgb(102,102,0)"><</=
span><span style=3D"font-family:monospace;background-color:rgb(250,250,250)=
;color:rgb(0,0,136)">class</span><span style=3D"font-family:monospace;backg=
round-color:rgb(250,250,250)">=C2=A0T</span><span style=3D"font-family:mono=
space;background-color:rgb(250,250,250);color:rgb(102,102,0)">></span><s=
pan style=3D"font-family:monospace;background-color:rgb(250,250,250)"><br><=
/span><span style=3D"font-family:monospace;background-color:rgb(250,250,250=
)"><font color=3D"#000088">requires</font> is_arithmetic_v</span><span styl=
e=3D"font-family:monospace;background-color:rgb(250,250,250);color:rgb(102,=
102,0)"><</span><span style=3D"font-family:monospace;background-color:rg=
b(250,250,250)">T</span><span style=3D"font-family:monospace;background-col=
or:rgb(250,250,250);color:rgb(102,102,0)">></span><span style=3D"font-fa=
mily:monospace;background-color:rgb(250,250,250)"><br>void arith_ok</span><=
span style=3D"font-family:monospace;background-color:rgb(250,250,250);color=
:rgb(102,102,0)">(</span><span style=3D"font-family:monospace;background-co=
lor:rgb(250,250,250)">T t</span><span style=3D"font-family:monospace;backgr=
ound-color:rgb(250,250,250);color:rgb(102,102,0)">)</span><span style=3D"fo=
nt-family:monospace;background-color:rgb(250,250,250)">=C2=A0</span><span s=
tyle=3D"font-family:monospace;background-color:rgb(250,250,250);color:rgb(1=
02,102,0)">{</span><span style=3D"font-family:monospace;background-color:rg=
b(250,250,250)">=C2=A0cout=C2=A0</span><span style=3D"font-family:monospace=
;background-color:rgb(250,250,250);color:rgb(102,102,0)"><<</span><sp=
an style=3D"font-family:monospace;background-color:rgb(250,250,250)">=C2=A0=
</span><span style=3D"font-family:monospace;background-color:rgb(250,250,25=
0);color:rgb(0,136,0)">"T is an arithmetic type\n"</span><span st=
yle=3D"font-family:monospace;background-color:rgb(250,250,250);color:rgb(10=
2,102,0)">;</span><span style=3D"font-family:monospace;background-color:rgb=
(250,250,250)">=C2=A0</span><span style=3D"font-family:monospace;background=
-color:rgb(250,250,250);color:rgb(102,102,0)">}</span><br></div><div dir=3D=
"auto"><br></div>which is IMO much clearer. Same goes for the variadic case=
with a fold expression.<br><br><div class=3D"gmail_quote" dir=3D"auto"><di=
v dir=3D"ltr">On Mon, Jul 2, 2018, 10:39 AM Paul Keir <<a href=3D"mailto=
:graham.keir@gmail.com">graham.keir@gmail.com</a>> wrote:<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div>In summary I propose the ad=
dition of a SFINAE-friendly typedef member type <span style=3D"font-family:=
courier new,monospace">sfinae_type</span>, assigned to void, to all of the =
boolean predicate type traits in the standard library.</div><div><br></div>=
<div>Type traits corresponding to binary predicates give their boolean resu=
lt in different ways. Most commonly, the instantiated type will contain a c=
onstant data member named <span style=3D"font-family:courier new,monospace"=
>value</span> which is equal either to <span style=3D"font-family:courier n=
ew,monospace">true</span> or <span style=3D"font-family:courier new,monospa=
ce">false</span>. This idiom can be observed in most type traits; such as <=
span style=3D"font-family:courier new,monospace">std::is_void</span>, <span=
style=3D"font-family:courier new,monospace">std::is_fundamental</span> or =
<span style=3D"font-family:courier new,monospace">std::is_const</span>. For=
example:<br><br><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px" class=3D"m_1550940=
669826666540prettyprint"><code class=3D"m_1550940669826666540prettyprint"><=
div class=3D"m_1550940669826666540subprettyprint"><span style=3D"color:#008=
" class=3D"m_1550940669826666540styled-by-prettify">static_assert</span><sp=
an style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">(=
</span><span style=3D"color:#008" class=3D"m_1550940669826666540styled-by-p=
rettify">true</span><span style=3D"color:#000" class=3D"m_15509406698266665=
40styled-by-prettify"> =C2=A0</span><span style=3D"color:#660" class=3D"m_1=
550940669826666540styled-by-prettify">=3D=3D</span><span style=3D"color:#00=
0" class=3D"m_1550940669826666540styled-by-prettify"> is_same</span><span s=
tyle=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify"><<=
/span><span style=3D"color:#008" class=3D"m_1550940669826666540styled-by-pr=
ettify">char</span><span style=3D"color:#660" class=3D"m_155094066982666654=
0styled-by-prettify">,</span><span style=3D"color:#008" class=3D"m_15509406=
69826666540styled-by-prettify">char</span><span style=3D"color:#660" class=
=3D"m_1550940669826666540styled-by-prettify">>::</span><span style=3D"co=
lor:#000" class=3D"m_1550940669826666540styled-by-prettify">value</span><sp=
an style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">)=
;</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-=
prettify"><br></span><span style=3D"color:#008" class=3D"m_1550940669826666=
540styled-by-prettify">static_assert</span><span style=3D"color:#660" class=
=3D"m_1550940669826666540styled-by-prettify">(</span><span style=3D"color:#=
008" class=3D"m_1550940669826666540styled-by-prettify">false</span><span st=
yle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"> </spa=
n><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-pretti=
fy">=3D=3D</span><span style=3D"color:#000" class=3D"m_1550940669826666540s=
tyled-by-prettify"> is_volatile</span><span style=3D"color:#080" class=3D"m=
_1550940669826666540styled-by-prettify"><char></span><span style=3D"c=
olor:#660" class=3D"m_1550940669826666540styled-by-prettify">::</span><span=
style=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">val=
ue</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by=
-prettify">);</span></div></code></div><br>For other type traits, the resul=
t is a member typedef type. For example, <span style=3D"font-family:courier=
new,monospace">std::add_pointer</span> or <span style=3D"font-family:couri=
er new,monospace">std::decay</span>. Furthermore, the type member result of=
some such traits, may or may not exist. Consequently the presence, or abse=
nce, of a typedef member within the instantiated type can correlate with tr=
ue or false respectively. <span style=3D"font-family:courier new,monospace"=
>std::common_type</span>, <span style=3D"font-family:courier new,monospace"=
>std::iterator_traits</span> and <span style=3D"font-family:courier new,mon=
ospace">std::result_of</span> execute this approach. For example:<br><br><d=
iv style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px" class=3D"m_1550940669826666540prettyp=
rint"><code class=3D"m_1550940669826666540prettyprint"><div class=3D"m_1550=
940669826666540subprettyprint"><span style=3D"color:#000" class=3D"m_155094=
0669826666540styled-by-prettify">iterator_traits</span><span style=3D"color=
:#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><span s=
tyle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">vecto=
r</span><span style=3D"color:#080" class=3D"m_1550940669826666540styled-by-=
prettify"><int></span><span style=3D"color:#660" class=3D"m_155094066=
9826666540styled-by-prettify">::</span><span style=3D"color:#000" class=3D"=
m_1550940669826666540styled-by-prettify">iterator</span><span style=3D"colo=
r:#660" class=3D"m_1550940669826666540styled-by-prettify">>::</span><spa=
n style=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">di=
fference_type diff_t</span><span style=3D"color:#660" class=3D"m_1550940669=
826666540styled-by-prettify">;</span><span style=3D"color:#000" class=3D"m_=
1550940669826666540styled-by-prettify"><br>common_type</span><span style=3D=
"color:#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><=
span style=3D"color:#008" class=3D"m_1550940669826666540styled-by-prettify"=
>int</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-=
by-prettify">,</span><span style=3D"color:#008" class=3D"m_1550940669826666=
540styled-by-prettify">int</span><span style=3D"color:#660" class=3D"m_1550=
940669826666540styled-by-prettify">*>::</span><span style=3D"color:#000"=
class=3D"m_1550940669826666540styled-by-prettify">type =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 ct_t</span><span style=3D"color:#660" class=3D"m_1550940669826666540=
styled-by-prettify">;</span><span style=3D"color:#000" class=3D"m_155094066=
9826666540styled-by-prettify"> </span><span style=3D"color:#800" class=3D"m=
_1550940669826666540styled-by-prettify">// error</span><span style=3D"color=
:#000" class=3D"m_1550940669826666540styled-by-prettify"><br>result_of</spa=
n><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-pretti=
fy"><</span><span style=3D"color:#000" class=3D"m_1550940669826666540sty=
led-by-prettify">plus</span><span style=3D"color:#080" class=3D"m_155094066=
9826666540styled-by-prettify"><int></span><span style=3D"color:#660" =
class=3D"m_1550940669826666540styled-by-prettify">(</span><span style=3D"co=
lor:#008" class=3D"m_1550940669826666540styled-by-prettify">int</span><span=
style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">,</=
span><span style=3D"color:#008" class=3D"m_1550940669826666540styled-by-pre=
ttify">char</span><span style=3D"color:#660" class=3D"m_1550940669826666540=
styled-by-prettify">*)>::</span><span style=3D"color:#000" class=3D"m_15=
50940669826666540styled-by-prettify">type =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ro_t</span><span style=3D"color:#660" class=
=3D"m_1550940669826666540styled-by-prettify">;</span><span style=3D"color:#=
000" class=3D"m_1550940669826666540styled-by-prettify"> </span><span style=
=3D"color:#800" class=3D"m_1550940669826666540styled-by-prettify">// error<=
/span></div></code></div><br>The latter approach can be described as SFINAE=
-friendly, in that a non-existent trait result will not produce an error wh=
en involved in an invalid substitution of template parameters. For example,=
consider the use of <span style=3D"font-family:courier new,monospace">std:=
:common_type_t</span> in the definition of the overloaded binary subtract o=
perator for <span style=3D"font-family:courier new,monospace">std::duration=
</span>. Shown below, this function will not be instantiated when there is =
insufficient commonality between the types of its two arguments:<br><br><di=
v style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);=
border-style:solid;border-width:1px" class=3D"m_1550940669826666540prettypr=
int"><code class=3D"m_1550940669826666540prettyprint"><div class=3D"m_15509=
40669826666540subprettyprint"><span style=3D"color:#008" class=3D"m_1550940=
669826666540styled-by-prettify">template</span><span style=3D"color:#000" c=
lass=3D"m_1550940669826666540styled-by-prettify"> </span><span style=3D"col=
or:#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><span=
style=3D"color:#008" class=3D"m_1550940669826666540styled-by-prettify">cla=
ss</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by=
-prettify"> </span><span style=3D"color:#606" class=3D"m_155094066982666654=
0styled-by-prettify">Rep1</span><span style=3D"color:#660" class=3D"m_15509=
40669826666540styled-by-prettify">,</span><span style=3D"color:#000" class=
=3D"m_1550940669826666540styled-by-prettify"> </span><span style=3D"color:#=
008" class=3D"m_1550940669826666540styled-by-prettify">class</span><span st=
yle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"> </spa=
n><span style=3D"color:#606" class=3D"m_1550940669826666540styled-by-pretti=
fy">Period1</span><span style=3D"color:#660" class=3D"m_1550940669826666540=
styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_155094066=
9826666540styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m=
_1550940669826666540styled-by-prettify">class</span><span style=3D"color:#0=
00" class=3D"m_1550940669826666540styled-by-prettify"> </span><span style=
=3D"color:#606" class=3D"m_1550940669826666540styled-by-prettify">Rep2</spa=
n><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-pretti=
fy">,</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled=
-by-prettify"> </span><span style=3D"color:#008" class=3D"m_155094066982666=
6540styled-by-prettify">class</span><span style=3D"color:#000" class=3D"m_1=
550940669826666540styled-by-prettify"> </span><span style=3D"color:#606" cl=
ass=3D"m_1550940669826666540styled-by-prettify">Period2</span><span style=
=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">></spa=
n><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-pretti=
fy"><br>common_type_t</span><span style=3D"color:#660" class=3D"m_155094066=
9826666540styled-by-prettify"><</span><span style=3D"color:#000" class=
=3D"m_1550940669826666540styled-by-prettify">duration</span><span style=3D"=
color:#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><s=
pan style=3D"color:#606" class=3D"m_1550940669826666540styled-by-prettify">=
Rep1</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-=
by-prettify">,</span><span style=3D"color:#000" class=3D"m_1550940669826666=
540styled-by-prettify"> </span><span style=3D"color:#606" class=3D"m_155094=
0669826666540styled-by-prettify">Period1</span><span style=3D"color:#660" c=
lass=3D"m_1550940669826666540styled-by-prettify">>,</span><span style=3D=
"color:#000" class=3D"m_1550940669826666540styled-by-prettify"> duration</s=
pan><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-pret=
tify"><</span><span style=3D"color:#606" class=3D"m_1550940669826666540s=
tyled-by-prettify">Rep2</span><span style=3D"color:#660" class=3D"m_1550940=
669826666540styled-by-prettify">,</span><span style=3D"color:#000" class=3D=
"m_1550940669826666540styled-by-prettify"> </span><span style=3D"color:#606=
" class=3D"m_1550940669826666540styled-by-prettify">Period2</span><span sty=
le=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">>>=
;</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-=
prettify"><br></span><span style=3D"color:#008" class=3D"m_1550940669826666=
540styled-by-prettify">constexpr</span><span style=3D"color:#000" class=3D"=
m_1550940669826666540styled-by-prettify"> </span><span style=3D"color:#008"=
class=3D"m_1550940669826666540styled-by-prettify">operator</span><span sty=
le=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">-(</spa=
n><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-pretti=
fy"> </span><span style=3D"color:#008" class=3D"m_1550940669826666540styled=
-by-prettify">const</span><span style=3D"color:#000" class=3D"m_15509406698=
26666540styled-by-prettify"> duration</span><span style=3D"color:#660" clas=
s=3D"m_1550940669826666540styled-by-prettify"><</span><span style=3D"col=
or:#606" class=3D"m_1550940669826666540styled-by-prettify">Rep1</span><span=
style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">,</=
span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-pre=
ttify"> </span><span style=3D"color:#606" class=3D"m_1550940669826666540sty=
led-by-prettify">Period1</span><span style=3D"color:#660" class=3D"m_155094=
0669826666540styled-by-prettify">>&</span><span style=3D"color:#000"=
class=3D"m_1550940669826666540styled-by-prettify"> lhs<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=
=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">,</span><=
span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"=
> </span><span style=3D"color:#008" class=3D"m_1550940669826666540styled-by=
-prettify">const</span><span style=3D"color:#000" class=3D"m_15509406698266=
66540styled-by-prettify"> duration</span><span style=3D"color:#660" class=
=3D"m_1550940669826666540styled-by-prettify"><</span><span style=3D"colo=
r:#606" class=3D"m_1550940669826666540styled-by-prettify">Rep2</span><span =
style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">,</s=
pan><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-pret=
tify"> </span><span style=3D"color:#606" class=3D"m_1550940669826666540styl=
ed-by-prettify">Period2</span><span style=3D"color:#660" class=3D"m_1550940=
669826666540styled-by-prettify">>&</span><span style=3D"color:#000" =
class=3D"m_1550940669826666540styled-by-prettify"> rhs<br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"c=
olor:#660" class=3D"m_1550940669826666540styled-by-prettify">);</span></div=
></code></div><br>We propose that a SFINAE-friendly member typedef type nam=
ed <span style=3D"font-family:courier new,monospace">sfinae_type</span> ass=
igned to void be added to all binary predicate type traits. For example, wh=
ereas <span style=3D"font-family:courier new,monospace">std::is_same<cha=
r,int>::sfinae_type</span> would not be a valid name; <span style=3D"fon=
t-family:courier new,monospace">std::is_scalar<int>::sfinae_type</spa=
n> would be. Consequently, a function valid only for arguments of arithmeti=
c type could be written:<br><br><div style=3D"background-color:rgb(250,250,=
250);border-color:rgb(187,187,187);border-style:solid;border-width:1px" cla=
ss=3D"m_1550940669826666540prettyprint"><code class=3D"m_155094066982666654=
0prettyprint"><div class=3D"m_1550940669826666540subprettyprint"><span styl=
e=3D"color:#008" class=3D"m_1550940669826666540styled-by-prettify">template=
</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-p=
rettify"> </span><span style=3D"color:#660" class=3D"m_1550940669826666540s=
tyled-by-prettify"><</span><span style=3D"color:#008" class=3D"m_1550940=
669826666540styled-by-prettify">class</span><span style=3D"color:#000" clas=
s=3D"m_1550940669826666540styled-by-prettify"> T</span><span style=3D"color=
:#660" class=3D"m_1550940669826666540styled-by-prettify">></span><span s=
tyle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"><br><=
/span><span style=3D"color:#008" class=3D"m_1550940669826666540styled-by-pr=
ettify">typename</span><span style=3D"color:#000" class=3D"m_15509406698266=
66540styled-by-prettify"> is_arithmetic</span><span style=3D"color:#660" cl=
ass=3D"m_1550940669826666540styled-by-prettify"><</span><span style=3D"c=
olor:#000" class=3D"m_1550940669826666540styled-by-prettify">T</span><span =
style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">>=
::</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-by=
-prettify">sfinae_type<br>arith_ok</span><span style=3D"color:#660" class=
=3D"m_1550940669826666540styled-by-prettify">(</span><span style=3D"color:#=
000" class=3D"m_1550940669826666540styled-by-prettify">T t</span><span styl=
e=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">)</span>=
<span style=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify=
"> </span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-b=
y-prettify">{</span><span style=3D"color:#000" class=3D"m_15509406698266665=
40styled-by-prettify"> cout </span><span style=3D"color:#660" class=3D"m_15=
50940669826666540styled-by-prettify"><<</span><span style=3D"color:#0=
00" class=3D"m_1550940669826666540styled-by-prettify"> </span><span style=
=3D"color:#080" class=3D"m_1550940669826666540styled-by-prettify">"T i=
s an arithmetic type\n"</span><span style=3D"color:#660" class=3D"m_15=
50940669826666540styled-by-prettify">;</span><span style=3D"color:#000" cla=
ss=3D"m_1550940669826666540styled-by-prettify"> </span><span style=3D"color=
:#660" class=3D"m_1550940669826666540styled-by-prettify">}</span></div></co=
de></div></div><div><br></div><div>The useful C++17 type trait <span style=
=3D"font-family:courier new,monospace">std::void_t</span> then allows a con=
junction of standard traits:<br><br><div style=3D"background-color:rgb(250,=
250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"=
class=3D"m_1550940669826666540prettyprint"><code class=3D"m_15509406698266=
66540prettyprint"><div class=3D"m_1550940669826666540subprettyprint"><span =
style=3D"color:#008" class=3D"m_1550940669826666540styled-by-prettify">temp=
late</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-=
by-prettify"><</span><span style=3D"color:#008" class=3D"m_1550940669826=
666540styled-by-prettify">typename</span><span style=3D"color:#000" class=
=3D"m_1550940669826666540styled-by-prettify"> T</span><span style=3D"color:=
#660" class=3D"m_1550940669826666540styled-by-prettify">,</span><span style=
=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"> </span><=
span style=3D"color:#008" class=3D"m_1550940669826666540styled-by-prettify"=
>typename</span><span style=3D"color:#660" class=3D"m_1550940669826666540st=
yled-by-prettify">...</span><span style=3D"color:#000" class=3D"m_155094066=
9826666540styled-by-prettify"> </span><span style=3D"color:#606" class=3D"m=
_1550940669826666540styled-by-prettify">Ts</span><span style=3D"color:#660"=
class=3D"m_1550940669826666540styled-by-prettify">></span><span style=
=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"><br>void_=
t</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-=
prettify"><</span><span style=3D"color:#008" class=3D"m_1550940669826666=
540styled-by-prettify">typename</span><span style=3D"color:#000" class=3D"m=
_1550940669826666540styled-by-prettify"> is_same</span><span style=3D"color=
:#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><span s=
tyle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">T</sp=
an><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prett=
ify">,</span><span style=3D"color:#000" class=3D"m_1550940669826666540style=
d-by-prettify"> </span><span style=3D"color:#606" class=3D"m_15509406698266=
66540styled-by-prettify">Ts</span><span style=3D"color:#660" class=3D"m_155=
0940669826666540styled-by-prettify">>::</span><span style=3D"color:#000"=
class=3D"m_1550940669826666540styled-by-prettify">sfinae_type</span><span =
style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">...&=
gt;</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled-b=
y-prettify"><br>func</span><span style=3D"color:#660" class=3D"m_1550940669=
826666540styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_=
1550940669826666540styled-by-prettify">T</span><span style=3D"color:#660" c=
lass=3D"m_1550940669826666540styled-by-prettify">,</span><span style=3D"col=
or:#000" class=3D"m_1550940669826666540styled-by-prettify"> </span><span st=
yle=3D"color:#606" class=3D"m_1550940669826666540styled-by-prettify">Ts</sp=
an><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prett=
ify">...)</span><span style=3D"color:#000" class=3D"m_1550940669826666540st=
yled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_15509406698=
26666540styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_1=
550940669826666540styled-by-prettify"> cout </span><span style=3D"color:#66=
0" class=3D"m_1550940669826666540styled-by-prettify"><<</span><span s=
tyle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"> </sp=
an><span style=3D"color:#080" class=3D"m_1550940669826666540styled-by-prett=
ify">"all types in pack are T\n"</span><span style=3D"color:#660"=
class=3D"m_1550940669826666540styled-by-prettify">;</span><span style=3D"c=
olor:#000" class=3D"m_1550940669826666540styled-by-prettify"> </span><span =
style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify">}</s=
pan></div></code></div><br>Type traits such as <span style=3D"font-family:c=
ourier new,monospace">std::enable_if</span> and <span style=3D"font-family:=
courier new,monospace">std::void_t</span> facilitate further composition of=
predicates in the construction of SFINAE type expressions. The <span style=
=3D"font-family:courier new,monospace">sfinae_type</span> member would also=
be added to the C++17 traits <span style=3D"font-family:courier new,monosp=
ace">std::conjunction</span>, <span style=3D"font-family:courier new,monosp=
ace">std::disjunction</span>, and <span style=3D"font-family:courier new,mo=
nospace">std::negate</span>. Consequently, a function which is valid for ar=
guments of arithmetic type, but not types which are an <span style=3D"font-=
family:courier new,monospace">std::nullptr_t</span> or an enumeration type =
could look as follows:</div><div><br><div style=3D"background-color:rgb(250=
,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px=
" class=3D"m_1550940669826666540prettyprint"><code class=3D"m_1550940669826=
666540prettyprint"><div class=3D"m_1550940669826666540subprettyprint"><span=
style=3D"color:#008" class=3D"m_1550940669826666540styled-by-prettify">tem=
plate</span><span style=3D"color:#000" class=3D"m_1550940669826666540styled=
-by-prettify"> </span><span style=3D"color:#660" class=3D"m_155094066982666=
6540styled-by-prettify"><</span><span style=3D"color:#008" class=3D"m_15=
50940669826666540styled-by-prettify">class</span><span style=3D"color:#000"=
class=3D"m_1550940669826666540styled-by-prettify"> T</span><span style=3D"=
color:#660" class=3D"m_1550940669826666540styled-by-prettify">></span><s=
pan style=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">=
<br></span><span style=3D"color:#008" class=3D"m_1550940669826666540styled-=
by-prettify">typename</span><span style=3D"color:#000" class=3D"m_155094066=
9826666540styled-by-prettify"> conjunction</span><span style=3D"color:#660"=
class=3D"m_1550940669826666540styled-by-prettify"><</span><span style=
=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0is_scalar</span><span style=3D"color:=
#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><span st=
yle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">T</spa=
n><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-pretti=
fy">>,</span><span style=3D"color:#000" class=3D"m_1550940669826666540st=
yled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0negation</sp=
an><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prett=
ify"><</span><span style=3D"color:#000" class=3D"m_1550940669826666540st=
yled-by-prettify"> disjunction</span><span style=3D"color:#660" class=3D"m_=
1550940669826666540styled-by-prettify"><</span><span style=3D"color:#000=
" class=3D"m_1550940669826666540styled-by-prettify"> is_null_pointer</span>=
<span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-prettify=
"><</span><span style=3D"color:#000" class=3D"m_1550940669826666540style=
d-by-prettify">T</span><span style=3D"color:#660" class=3D"m_15509406698266=
66540styled-by-prettify">>,</span><span style=3D"color:#000" class=3D"m_=
1550940669826666540styled-by-prettify"> is_enum</span><span style=3D"color:=
#660" class=3D"m_1550940669826666540styled-by-prettify"><</span><span st=
yle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify">T</spa=
n><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-pretti=
fy">></span><span style=3D"color:#000" class=3D"m_1550940669826666540sty=
led-by-prettify"> </span><span style=3D"color:#660" class=3D"m_155094066982=
6666540styled-by-prettify">></span><span style=3D"color:#000" class=3D"m=
_1550940669826666540styled-by-prettify"> </span><span style=3D"color:#660" =
class=3D"m_1550940669826666540styled-by-prettify">></span><span style=3D=
"color:#000" class=3D"m_1550940669826666540styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660" class=3D"m_155=
0940669826666540styled-by-prettify">>::</span><span style=3D"color:#000"=
class=3D"m_1550940669826666540styled-by-prettify">sfinae_type<br>arith_ptr=
_or_memptr</span><span style=3D"color:#660" class=3D"m_1550940669826666540s=
tyled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_1550940669=
826666540styled-by-prettify">T</span><span style=3D"color:#660" class=3D"m_=
1550940669826666540styled-by-prettify">)</span><span style=3D"color:#000" c=
lass=3D"m_1550940669826666540styled-by-prettify"> </span><span style=3D"col=
or:#660" class=3D"m_1550940669826666540styled-by-prettify">{</span><span st=
yle=3D"color:#000" class=3D"m_1550940669826666540styled-by-prettify"> cout =
</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled-by-p=
rettify"><<</span><span style=3D"color:#000" class=3D"m_1550940669826=
666540styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_155=
0940669826666540styled-by-prettify">"arithmetic, ptr, or member ptr\n&=
quot;</span><span style=3D"color:#660" class=3D"m_1550940669826666540styled=
-by-prettify">;</span><span style=3D"color:#000" class=3D"m_155094066982666=
6540styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_15509=
40669826666540styled-by-prettify">}</span></div></code></div><br>Sample cod=
e is available at <a href=3D"https://wandbox.org/permlink/o0fIFssB6Gl6oRKS"=
target=3D"_blank" rel=3D"noreferrer">https://wandbox.org/permlink/o0fIFssB=
6Gl6oRKS</a>. The code uses the <span style=3D"font-family:courier new,mono=
space">mk_sfinae</span> helper to construct a trait from an existing trait =
and its template arguments.<br></div><div><br></div><div>Feedback is most w=
elcome.<br></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" target=3D"_=
blank" rel=3D"noreferrer">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" rel=3D"noreferrer">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/17994533-9542-4403-b447-963cb85d29e6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/17994533-9542-4403-b447-963cb85d29e6%40isocpp.org</a>.<br>
</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" 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/CALmDwq14yUxEfAiFF%2B1m0qtM%2BugAoxNu=
M%3D4wWDK6o6ZhG5%2BtcA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALmDwq14=
yUxEfAiFF%2B1m0qtM%2BugAoxNuM%3D4wWDK6o6ZhG5%2BtcA%40mail.gmail.com</a>.<br=
/>
--000000000000b21106057001436f--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 2 Jul 2018 07:20:33 -0700 (PDT)
Raw View
------=_Part_14265_1636419262.1530541233547
Content-Type: multipart/alternative;
boundary="----=_Part_14266_653778258.1530541233548"
------=_Part_14266_653778258.1530541233548
Content-Type: text/plain; charset="UTF-8"
Isn't C++20's concepts and `requires` clause going to do away with SFINAE
pretty much entirely? Use of concepts basically trivializes all of your
examples, removing the cruft and leaving only the intent. Observe:
On Monday, July 2, 2018 at 4:39:23 AM UTC-4, Paul Keir wrote:
>
> template <class T>
> typename is_arithmetic<T>::sfinae_type
> arith_ok(T t) { cout << "T is an arithmetic type\n"; }
>
>
template<IsArithmetic T>
arith_ok(T t) {...}
> template<typename T, typename... Ts>
> void_t<typename is_same<T, Ts>::sfinae_type...>
> func(T, Ts...) { cout << "all types in pack are T\n"; }
>
>
template<typename T, typename ... Ts>
requires IsSame<T, Ts> && ...
void func(T, Ts...) {...}
template <class T>
> typename conjunction<
> is_scalar<T>,
> negation< disjunction< is_null_pointer<T>, is_enum<T> > >
> >::sfinae_type
> arith_ptr_or_memptr(T) { cout << "arithmetic, ptr, or member ptr\n"; }
>
>
template<typename T>
requires IsScalar<T> && !(IsNullPointer<T> || IsEnum<T>)
void arith_ptr_or_memptr(T) { ... }
Aren't these all infinitely better and more readable than the
`void_t`/`conjunction`/etc nonsense? Let us *bury* SFINAE, not promote it.
--
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/348776cc-8d99-4bfb-aff1-3b14ec8d2167%40isocpp.org.
------=_Part_14266_653778258.1530541233548
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Isn't C++20's concepts and `requires` clause =
going to do away with SFINAE pretty much entirely? Use of concepts basicall=
y trivializes all of your examples, removing the cruft and leaving only the=
intent. Observe:</div><br>On Monday, July 2, 2018 at 4:39:23 AM UTC-4, Pau=
l Keir 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">=
<div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,1=
87,187);border-style:solid;border-width:1px"><code><div><span style=3D"colo=
r:#008">template</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#008">class</span><span style=3D"=
color:#000"> T</span><span style=3D"color:#660">></span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#008">typename</span><span style=
=3D"color:#000"> is_arithmetic</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">sfinae_type<br>arith_ok</span><span style=3D"col=
or:#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"> cout </span><span style=3D"color:#660"=
><<</span><span style=3D"color:#000"> </span><span style=3D"color:#08=
0">"T is an arithmetic type\n"</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</spa=
n></div></code></div></div><div><br></div></div></blockquote><div><br></div=
><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187,=
187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-wo=
rd;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templat=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">IsArithmetic</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>arith_ok</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">T t</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{...}</span></div></code></div><div>=C2=A0</div><blockquote=
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></div><div><div sty=
le=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);borde=
r-style:solid;border-width:1px"><code><div><span style=3D"color:#008">templ=
ate</span><span style=3D"color:#660"><</span><span style=3D"color:#008">=
typename</span><span style=3D"color:#000"> T</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#660">...</span><span style=3D"color:#000=
"> </span><span style=3D"color:#606">Ts</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"><br>void_t</span><span style=3D"color:#=
660"><</span><span style=3D"color:#008">typename</span><span style=3D"co=
lor:#000"> is_same</span><span style=3D"color:#660"><</span><span style=
=3D"color:#000">T</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#606">Ts</span><span style=3D"color=
:#660">>::</span><span style=3D"color:#000">sfinae_type</span><span styl=
e=3D"color:#660">...></span><span style=3D"color:#000"><br>func</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">T</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">Ts</span><span style=3D"color:#660">...)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> cout </span><span style=3D"color:#660"><<</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#080">"all types in pac=
k are T\n"</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">}</span></div></code></div><br>=
</div></div></blockquote><div>=C2=A0</div><div style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">template</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ty=
pename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><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: #606;" class=3D"styled-by-prettify">Ts</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 requires </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">IsSame</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #00=
0;" 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"style=
d-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pret=
tify">Ts</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</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"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> func</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"> <=
/span><span style=3D"color: #606;" class=3D"styled-by-prettify">Ts</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">...)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{...}</span></div></code></div><di=
v><br></div><div></div><div></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 style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><=
div><span style=3D"color:#008">template</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660"><</span><span style=3D"color:#008">clas=
s</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:#008">typ=
ename</span><span style=3D"color:#000"> conjunction</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0is_scalar</span><span style=3D"color:#660"><</span><=
span style=3D"color:#000">T</span><span style=3D"color:#660">>,</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0negat=
ion</span><span style=3D"color:#660"><</span><span style=3D"color:#000">=
disjunction</span><span style=3D"color:#660"><</span><span style=3D"col=
or:#000"> is_null_pointer</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"> is_enum</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"> </span><span style=3D"color:#660">></span><span=
style=3D"color:#000"> </span><span style=3D"color:#660">></span><span s=
tyle=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span styl=
e=3D"color:#660">>::</span><span style=3D"color:#000">sfinae_type<br>ari=
th_ptr_or_memptr</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#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">=
cout </span><span style=3D"color:#660"><<</span><span style=3D"color=
:#000"> </span><span style=3D"color:#080">"arithmetic, ptr, or member =
ptr\n"</span><span style=3D"color:#660">;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">}</span></div></code></div><br></di=
v></div></blockquote><div><br></div><div style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;"=
class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 requires </span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">IsScalar</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">></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"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">!(</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">IsNullPointer</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">||</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">IsEnum</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">>)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></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"> arith_ptr_or_memptr</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;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></co=
de></div><div></div><div><br></div><div></div><div>Aren't these all inf=
initely better and more readable than the `void_t`/`conjunction`/etc nonsen=
se? Let us <i>bury</i> SFINAE, not promote it.<br></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/348776cc-8d99-4bfb-aff1-3b14ec8d2167%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/348776cc-8d99-4bfb-aff1-3b14ec8d2167=
%40isocpp.org</a>.<br />
------=_Part_14266_653778258.1530541233548--
------=_Part_14265_1636419262.1530541233547--
.