220 33441 <6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: james.a.cooper@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Proposal: underlying_cast
Date: Sun, 30 Jul 2017 04:50:41 -0700 (PDT)
Lines: 487
Approved: news@gmane.org
Message-ID: <6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_3238_804273539.1501415441388"
X-Trace: blaine.gmane.org 1501415443 16830 195.159.176.226 (30 Jul 2017 11:50:43 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 30 Jul 2017 11:50:43 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCR6HLXQUAORBEUQ67FQKGQEFV4JC4I@isocpp.org Sun Jul 30 13:50:39 2017
Return-path: <std-proposals+bncBCR6HLXQUAORBEUQ67FQKGQEFV4JC4I@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qk0-f200.google.com ([209.85.220.200])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCR6HLXQUAORBEUQ67FQKGQEFV4JC4I@isocpp.org>)
	id 1dbmk2-00045j-5r
	for gclcip-std-proposals@m.gmane.org; Sun, 30 Jul 2017 13:50:38 +0200
Original-Received: by mail-qk0-f200.google.com with SMTP id d136sf82619491qkg.11
        for <gclcip-std-proposals@m.gmane.org>; Sun, 30 Jul 2017 04:50:44 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=68Ok3E/RXdo1ATumOJbmjT4589jnW1IIZ05zWMy5evA=;
        b=dAd2rmuqigMTy5mrr9ZqDiXUHB5o0SsP0fPrGtmKGyeA9fAjLemmpmLtoIgKFFSswV
         3XoWApov+13jI7GGRfFvlKcl4326cN1yiiIM4x5L+JwxGKyUybYGZTNC7xVaXLGozcXy
         2A4Y5ogeV8MNwd3In5TokBDh01B2xUgiBjZssl1XO4F66+Yflrz2QLhonUX4dkkcYHl2
         zBaR6zPawCjYBy6/F94ppbQl6BbiDb1eXqPIudzct1dCJj41fkOGps15XeGFwzUo4kTy
         HN45nvyGFFNw6OQXvV6ATHWTO8AN1o5t6RkbIqPR0lq6YKmbqRwe43V1/vLObvYZ73sF
         60ng==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=68Ok3E/RXdo1ATumOJbmjT4589jnW1IIZ05zWMy5evA=;
        b=omBIDcx+ZZfnY8dfujkV599gg9Q3xMqZQzEFAvfoyfs61/gPp2gwM2S3C/2TistKrl
         O/Bp/kgLq1OA+GOWtbAwL3zChNsJYZSZvp5brJzwIIw/owmuXy8QKlcgG6iuPNtqpRbJ
         pXsEzwzT71sf77nNOtw+r45fhK8VllEzFeV/pessOVnFG6e+vHj4Q3DOYX0oTaUsePoy
         QhjvDhwaLpVaCKe9t/dzo4MMR+8ihUjXbFvX2k/2h1LthufAyptj2+1oJKkTMegiDK95
         GwyxogKRMHP0Gqa53/QtDQsWyKpxleZNryKSX1eZGfUkoBTHUobRF0rEKbpzR8QusL4M
         cvBg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=68Ok3E/RXdo1ATumOJbmjT4589jnW1IIZ05zWMy5evA=;
        b=qU4zfqYeMpIv71z//8EcJicMvWNjBLMwmxDHMhMaThHFZqPEWcAK3gwSL1FQcvBgjV
         iof6XXUukertNHdGOLrs8/vmrjHJJ9SuK6ZeVbX18Rxgdo/M/LLK7K3LuxEvwfK4rwu/
         i7ZtXIqlUKRhI7th6l9TQxBXZFruJ31yQmGPYwuRNb0c9yFp/j00mEo7u2bSTs65eZyc
         1RDbnpd1uqxyIfF8Pad7OIvzQ8NV1XBKLxHitnjH1/6uzK1GflPOizQd6+OksFzXBPwc
         i3NOrQYcoZd/a+sBJOzjc1pL9AF3PSfS4yvG78ix0iKUFNtqjql0c0JP33suQlpkv/Fo
         e2yw==
X-Gm-Message-State: AIVw113GGm70jpNwEbGj5NUxKCaS0WgzaczzHo9CkRH003M4cAIV9Ewy
	JPAuGTNy/hGyzoXh
X-Received: by 10.237.62.245 with SMTP id o50mr9260034qtf.35.1501415443502;
        Sun, 30 Jul 2017 04:50:43 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.36.138.134 with SMTP id v128ls6692028itd.15.gmail; Sun, 30 Jul
 2017 04:50:42 -0700 (PDT)
X-Received: by 10.31.49.205 with SMTP id x196mr68389vkx.2.1501415441894;
        Sun, 30 Jul 2017 04:50:41 -0700 (PDT)
X-Original-Sender: james.a.cooper@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:33441
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/33441>

------=_Part_3238_804273539.1501415441388
Content-Type: multipart/alternative; 
	boundary="----=_Part_3239_836813329.1501415441390"

------=_Part_3239_836813329.1501415441390
Content-Type: text/plain; charset="UTF-8"

C++ allows enums to have an underlying type specified. When serialising 
enum values it's important to use the correct type.
This proposal is to add a utility function that casts an enum type to its 
underlying value. This would make it easier to handle
enum types in function overloads for serialisation. For example:

template <typename T>
std::ostream& write(std::ostream& os, const T& v)
{
    os << std::underlying_cast(v);
    return os;
}


This function would, in the case of enums cast the value to the underlying 
type, and in the case of any other type it would do nothing.
One possible implementation:

template <typename E>
using UnderlyingType = typename std::underlying_type<E>::type;

template <typename E>
using EnumTypesOnly = typename std::enable_if<std::is_enum<E>::value, E>::
type;

template <typename T>
using NotEnumTypesOnly = typename std::enable_if<!std::is_enum<T>::value, T
>::type;


// For enums do the cast.
template <typename E, typename = EnumTypesOnly<E>>
constexpr UnderlyingType<E> underlying_cast(E e)
{
   return static_cast<UnderlyingType<E>>(e);
}

// For other types do nothing.
template <typename T, typename = NotEnumTypesOnly<T>>
constexpr T underlying_cast(T t)
{
   return t;
}



The reason this is required is that even when the enum type is explicitly 
set, it can be ignored during function overloading.
For example:

enum AnEnum : bool { A, B };

//void print(AnEnum) { std::cout << "print(AnEnum)\n"; }
void print(int) { std::cout << "print(int)\n"; }
void print(bool) { std::cout << "print(bool)\n"; }

int main(int argc, char* argv[])
{
    print(A); // Compiler chooses print(int) overload.
    return 0;
}

If, in the above code, the print(AnEnum) overload is removed, the compiler 
will choose the print(int) function despite the compiler being told that
the enum is a bool (additionally, if a 'C' value is added to the enum the 
compiler will complain).
If this value is being serialised to JSON, for example, this is not the 
intended outcome. The following code behaves as the programmer intended

enum AnEnum : bool { A, B };

void print(int) { std::cout << "print(int)\n"; }
void print(bool) { std::cout << "print(bool)\n"; }

int main(int argc, char* argv[])
{
    print(underlying_cast(A)); // Compiler chooses print(bool) overload.
    return 0;
}

-- 
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/6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3%40isocpp.org.

------=_Part_3239_836813329.1501415441390
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">C++ allows enums to have an underlying type specified. Whe=
n serialising enum values it&#39;s important to use the correct type.<br>Th=
is proposal is to add a utility function that casts an enum type to its und=
erlying value. This would make it easier to handle<br>enum types in functio=
n overloads for serialisation. For example:<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; overflow-wrap: break-word;=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span class=3D"=
styled-by-prettify" style=3D"color: #008;">template</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-p=
rettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-prettif=
y" style=3D"color: #008;">typename</span><span class=3D"styled-by-prettify"=
 style=3D"color: #000;"> T</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">&gt;</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br>std</span><span class=3D"styled-by-prettify" style=3D"color=
: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
>ostream</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&a=
mp;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> write<=
/span><span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #000;">std</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"sty=
led-by-prettify" style=3D"color: #000;">ostream</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">&amp;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"> os</span><span class=3D"styled-by-prettify=
" style=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">const</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"> T</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&amp=
;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> v</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">)</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 os </span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">&lt;&lt;</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=3D"st=
yled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;">underlying_cast</span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-pret=
tify" style=3D"color: #000;">v</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">);</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" sty=
le=3D"color: #008;">return</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> os</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
"><br></span><span class=3D"styled-by-prettify" style=3D"color: #660;">}</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span></=
div></code></div><br><br>This
 function would, in the case of enums cast the value to the underlying=20
type, and in the case of any other type it would do nothing.<br>One possibl=
e implementation:<br><br><div class=3D"prettyprint" style=3D"background-col=
or: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: sol=
id; border-width: 1px; overflow-wrap: break-word;"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" style=
=3D"color: #008;">template</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #008=
;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><s=
pan class=3D"styled-by-prettify" style=3D"color: #008;">using</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"s=
tyled-by-prettify" style=3D"color: #606;">UnderlyingType</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">=3D</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #008;">typename</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" style=3D"=
color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;">underlying_type</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #0=
00;">E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;=
::</span><span class=3D"styled-by-prettify" style=3D"color: #000;">type</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">;</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #008;">template</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styl=
ed-by-prettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-=
prettify" style=3D"color: #008;">typename</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"> E</span><span class=3D"styled-by-prettify" =
style=3D"color: #660;">&gt;</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"co=
lor: #008;">using</span><span class=3D"styled-by-prettify" style=3D"color: =
#000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #606;">En=
umTypesOnly</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> </span><span class=3D"styled-by-prettify" style=3D"color: #660;">=3D</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span c=
lass=3D"styled-by-prettify" style=3D"color: #008;">typename</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;">enable_if</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;">std</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;">is_enum</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;:=
:</span><span class=3D"styled-by-prettify" style=3D"color: #000;">value</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">,</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;"> E</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">&gt;::</span><span class=3D"sty=
led-by-prettify" style=3D"color: #000;">type</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"><br><br></span><span class=3D"styled-by-prettify" =
style=3D"color: #008;">template</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #=
008;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"> T</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span=
><span class=3D"styled-by-prettify" style=3D"color: #008;">using</span><spa=
n class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=
=3D"styled-by-prettify" style=3D"color: #606;">NotEnumTypesOnly</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">=3D</span><span class=3D"styled=
-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">typename</span><span class=3D"styled-by-prettif=
y" style=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #660;">::</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;">enable_if</span><span class=3D"styled-by-prettify" style=3D"col=
or: #660;">&lt;!</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;">std</span><span class=3D"styled-by-prettify" style=3D"color: #660;">:=
:</span><span class=3D"styled-by-prettify" style=3D"color: #000;">is_enum</=
span><span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;">T</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #660;">&gt;::</span><span class=3D=
"styled-by-prettify" style=3D"color: #000;">value</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #660;">,</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> T</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">&gt;::</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;">type</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000=
;"><br><br><br></span><span class=3D"styled-by-prettify" style=3D"color: #8=
00;">// For enums do the cast.</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"=
color: #008;">template</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #008;">typ=
ename</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> E</s=
pan><span class=3D"styled-by-prettify" style=3D"color: #660;">,</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D=
"styled-by-prettify" style=3D"color: #008;">typename</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-=
prettify" style=3D"color: #660;">=3D</span><span class=3D"styled-by-prettif=
y" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=
=3D"color: #606;">EnumTypesOnly</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D=
"color: #000;">E</span><span class=3D"styled-by-prettify" style=3D"color: #=
660;">&gt;&gt;</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #008;">co=
nstexpr</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #606;">UnderlyingTy=
pe</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;">E</span><span =
class=3D"styled-by-prettify" style=3D"color: #660;">&gt;</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> underlying_cast</span><span=
 class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=3D=
"styled-by-prettify" style=3D"color: #000;">E e</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;"><br>=C2=A0 =C2=A0</span><span class=3D"styled-by-prettify" sty=
le=3D"color: #008;">return</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">static_cast</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #60=
6;">UnderlyingType</span><span class=3D"styled-by-prettify" style=3D"color:=
 #660;">&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
">E</span><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;&gt=
;(</span><span class=3D"styled-by-prettify" style=3D"color: #000;">e</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">);</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">}</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"><br><br></span><span class=3D"styled-by-=
prettify" style=3D"color: #800;">// For other types do nothing.</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=
=3D"styled-by-prettify" style=3D"color: #008;">template</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">&lt;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #008;">typename</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> T</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">typename</span><span class=3D"styled-by-prettify" style=3D"color: #000;=
"> </span><span class=3D"styled-by-prettify" style=3D"color: #660;">=3D</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span =
class=3D"styled-by-prettify" style=3D"color: #606;">NotEnumTypesOnly</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">&lt;</span><span =
class=3D"styled-by-prettify" style=3D"color: #000;">T</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">&gt;&gt;</span><span class=3D"st=
yled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-b=
y-prettify" style=3D"color: #008;">constexpr</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"> T underlying_cast</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;">T t</span><span class=3D"styled-by-prettif=
y" style=3D"color: #660;">)</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">{</span><span class=3D"styled-by-prettify" style=3D"color: #000=
;"><br>=C2=A0 =C2=A0</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #008;">return</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;"> t</span><span class=3D"styled-by-prettify" style=3D"color: #660;">;<=
/span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">}</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span></div></cod=
e></div><br><br>The reason this is required is that even when the enum type=
 is explicitly set, it can be ignored during function overloading.<br>For e=
xample:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; overflow-wrap: break-word;"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: =
#008;">enum</span><span class=3D"styled-by-prettify" style=3D"color: #000;"=
> </span><span class=3D"styled-by-prettify" style=3D"color: #606;">AnEnum</=
span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><spa=
n class=3D"styled-by-prettify" style=3D"color: #660;">:</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"style=
d-by-prettify" style=3D"color: #008;">bool</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" =
style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"=
color: #000;"> A</span><span class=3D"styled-by-prettify" style=3D"color: #=
660;">,</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> B =
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">};</span><=
span class=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><sp=
an class=3D"styled-by-prettify" style=3D"color: #800;">//void print(AnEnum)=
 { std::cout &lt;&lt; &quot;print(AnEnum)\n&quot;; }</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"styled-=
by-prettify" style=3D"color: #008;">void</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" st=
yle=3D"color: #008;">print</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">(</span><span class=3D"styled-by-prettify" style=3D"color=
: #008;">int</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">)</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styled-=
by-prettify" style=3D"color: #000;">cout </span><span class=3D"styled-by-pr=
ettify" style=3D"color: #660;">&lt;&lt;</span><span class=3D"styled-by-pret=
tify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" sty=
le=3D"color: #080;">&quot;print(int)\n&quot;</span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify=
" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">}</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #008=
;">void</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #008;">print</span>=
<span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #008;">bool</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify=
" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">cout </span><span class=3D"styled-by-prettify" style=3D"color: #660;">&=
lt;&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #080;">&quot;print(=
bool)\n&quot;</span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">}</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #008;">int</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> main</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">int</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"> argc</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #008;">=
char</span><span class=3D"styled-by-prettify" style=3D"color: #660;">*</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> argv</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #660;">[])</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">print</span><span class=3D"styled-=
by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-pretti=
fy" style=3D"color: #000;">A</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">);</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #800;"=
>// Compiler chooses print(int) overload.</span><span class=3D"styled-by-pr=
ettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"styl=
ed-by-prettify" style=3D"color: #008;">return</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: #066;">0</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">;</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">}</span><span class=3D"styled-by-prettify" style=3D"color: #000;"><br></=
span></div></code></div><br>If,
 in the above code, the print(AnEnum) overload is removed, the compiler=20
will choose the print(int) function despite the compiler being told that<br=
>the enum is a bool (additionally, if a &#39;C&#39; value is added to the e=
num the compiler will complain).<br>If
 this value is being serialised to JSON, for example, this is not the=20
intended outcome. The following code behaves as the programmer intended<br>=
<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250=
); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px=
; overflow-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span class=3D"styled-by-prettify" style=3D"color: #0=
08;">enum</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> =
</span><span class=3D"styled-by-prettify" style=3D"color: #606;">AnEnum</sp=
an><span class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span =
class=3D"styled-by-prettify" style=3D"color: #660;">:</span><span class=3D"=
styled-by-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by=
-prettify" style=3D"color: #008;">bool</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" styl=
e=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"> A</span><span class=3D"styled-by-prettify" style=3D"color: #660;=
">,</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> B </sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">};</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=
=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">void</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: #008;">print</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #660;">(</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #008;">int</span><span class=3D"styled-by-prettify" style=3D"color: #6=
60;">)</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </s=
pan><span class=3D"styled-by-prettify" style=3D"color: #660;">{</span><span=
 class=3D"styled-by-prettify" style=3D"color: #000;"> std</span><span class=
=3D"styled-by-prettify" style=3D"color: #660;">::</span><span class=3D"styl=
ed-by-prettify" style=3D"color: #000;">cout </span><span class=3D"styled-by=
-prettify" style=3D"color: #660;">&lt;&lt;</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" =
style=3D"color: #080;">&quot;print(int)\n&quot;</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by-prett=
ify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettify" styl=
e=3D"color: #660;">}</span><span class=3D"styled-by-prettify" style=3D"colo=
r: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">void</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> <=
/span><span class=3D"styled-by-prettify" style=3D"color: #008;">print</span=
><span class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #008;">bool</span><span class=3D=
"styled-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-b=
y-prettify" style=3D"color: #000;"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"> std</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">cout </span><span class=3D"styled-by-prettify" style=3D"color: #660;">&=
lt;&lt;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </=
span><span class=3D"styled-by-prettify" style=3D"color: #080;">&quot;print(=
bool)\n&quot;</span><span class=3D"styled-by-prettify" style=3D"color: #660=
;">;</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> </spa=
n><span class=3D"styled-by-prettify" style=3D"color: #660;">}</span><span c=
lass=3D"styled-by-prettify" style=3D"color: #000;"><br><br></span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #008;">int</span><span class=3D"s=
tyled-by-prettify" style=3D"color: #000;"> main</span><span class=3D"styled=
-by-prettify" style=3D"color: #660;">(</span><span class=3D"styled-by-prett=
ify" style=3D"color: #008;">int</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"> argc</span><span class=3D"styled-by-prettify" style=
=3D"color: #660;">,</span><span class=3D"styled-by-prettify" style=3D"color=
: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #008;">=
char</span><span class=3D"styled-by-prettify" style=3D"color: #660;">*</spa=
n><span class=3D"styled-by-prettify" style=3D"color: #000;"> argv</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #660;">[])</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">{</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">print</span><span class=3D"styled-=
by-prettify" style=3D"color: #660;">(underlying_cast(</span><span class=3D"=
styled-by-prettify" style=3D"color: #000;">A)</span><span class=3D"styled-b=
y-prettify" style=3D"color: #660;">);</span><span class=3D"styled-by-pretti=
fy" style=3D"color: #000;"> // Compiler chooses print(bool) overload.<br>=
=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: #00=
8;">return</span><span class=3D"styled-by-prettify" style=3D"color: #000;">=
 </span><span class=3D"styled-by-prettify" style=3D"color: #066;">0</span><=
span class=3D"styled-by-prettify" style=3D"color: #660;">;</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #000;"><br></span><span class=3D"s=
tyled-by-prettify" style=3D"color: #660;">}</span><span class=3D"styled-by-=
prettify" style=3D"color: #000;"><br></span></div></code></div></div></code=
></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/6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6a2c32ed-99b5-4cc5-86a5-ee3cc07567a3=
%40isocpp.org</a>.<br />

------=_Part_3239_836813329.1501415441390--

------=_Part_3238_804273539.1501415441388--

.
