220 35426 <CAFQaeCBZXomwC+WK2rzg8VXi4EPz57Fo93fNh6w37oz7Hgqehg@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: j c <james.a.cooper@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Allow out-of-class operator overloading for enum classes
Date: Tue, 21 Nov 2017 16:58:34 +0000
Lines: 522
Approved: news@gmane.org
Message-ID: <CAFQaeCBZXomwC+WK2rzg8VXi4EPz57Fo93fNh6w37oz7Hgqehg@mail.gmail.com>
References: <b9b24701-fd4e-411b-91e1-608bba06fe96@isocpp.org>
 <608409c3-7708-4024-8ca5-8ecd566ca4a9@isocpp.org> <990fd030-20de-4bec-b11f-b43f9338667c@isocpp.org>
 <ouv6bl$hjh$1@blaine.gmane.org> <40465af3-4752-44b9-9367-cf2d1c41a335@isocpp.org>
 <ouvhb9$odv$1@blaine.gmane.org> <f8609d66-6c7e-4049-85c4-fa96ad58b2c9@isocpp.org>
 <CAFQaeCACa7Vn55v_wVcPDh=m=fMzoOvwLh4Dn+joswx=PV9CQg@mail.gmail.com> <bb14bcfe-f2fb-453e-834a-12e973d7ec57@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="089e082bdc600d44d1055e811d02"
X-Trace: blaine.gmane.org 1511283519 19586 195.159.176.226 (21 Nov 2017 16:58:39 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 21 Nov 2017 16:58:39 +0000 (UTC)
Cc: bop@gmb.dk
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCR6HLXQUAORBO5W2HIAKGQEHIHH7AI@isocpp.org Tue Nov 21 17:58:32 2017
Return-path: <std-proposals+bncBCR6HLXQUAORBO5W2HIAKGQEHIHH7AI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw0-f199.google.com ([209.85.161.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCR6HLXQUAORBO5W2HIAKGQEHIHH7AI@isocpp.org>)
	id 1eHBsT-0004WV-D8
	for gclcip-std-proposals@m.gmane.org; Tue, 21 Nov 2017 17:58:29 +0100
Original-Received: by mail-yw0-f199.google.com with SMTP id v195sf5898885ywg.18
        for <gclcip-std-proposals@m.gmane.org>; Tue, 21 Nov 2017 08:58:37 -0800 (PST)
ARC-Seal: i=2; a=rsa-sha256; t=1511283516; cv=pass;
        d=google.com; s=arc-20160816;
        b=Q7CltcHQ2qB07ERSHZJ5koUavKs5T7VxjPOB84qEVUR3XVHt7IEksyErefNBP/omgP
         3FtOsUUfZ55JLGM2LSEviY1yUnoLo1l0pOBPJVyLsToDzUKYyMJyxk7yglK7SIRirLMw
         bz3Iq8U1dV9EKLnkAGNo962k4Q5xSQ4Yc5KTScwl1RV6xc2YKfO4qmxuM9e20Us8tiKj
         rCmwDlaRiIXAezGBi/zMA3EokOeDWNejpDmyfz+hVC9N/c3dEE97Mb2CKiDLCcLE0Xxq
         C3gCfdxoJmHjAcDt+mK5mBd1YHHuHpyyzDYcyGfMCefnq7HbIlKDuMa4Zlt3RPeGIPdX
         aDDg==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post
         :list-id:mailing-list:precedence:reply-to:cc:to:subject:message-id
         :date:from:references:in-reply-to:mime-version
         :arc-authentication-results:arc-message-signature:dkim-signature
         :arc-authentication-results;
        bh=psk3TBz1xhojOg0RjWkH/6eCV+DWe0tBZbt+Fttn+Q0=;
        b=Tx3Cm2kmO+KqZljVdtltpK0uP7KcFTdpHGOdmc7/jOydoDvgtvZZEYD7CTlH0zQ+1O
         Em5707y1NBkh0GNN5vRVUnG7AnfohuIRmH8dS4UcGRDpKlJK6M3oGa3v3/SWZCprXc2v
         wSng3mLuDirNm6XjZ7LyTtSnOwTfVe4vdjn6HVEx6y5fGf/U6OPpVR8xUp6NRImNzN5M
         NGHGAJV0KymlvLsYb7xrP/jjZBu7F/JeyEu8uiPCJgRkwQ1JZ0976syhtUMG2IR+502F
         vVRCA7yIknUdf6cuBpS5E+qMpqsfs0KZdrKp497UaoQbHnUUHLAMcDTGJRNoAg/EjgOQ
         j60Q==
ARC-Authentication-Results: i=2; mx.google.com;
       dkim=pass header.i=@gmail.com header.s=20161025 header.b=l8Md6QOY;
       spf=pass (google.com: domain of james.a.cooper@gmail.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=james.a.cooper@gmail.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :cc:x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=psk3TBz1xhojOg0RjWkH/6eCV+DWe0tBZbt+Fttn+Q0=;
        b=DxH8I+8Ews4IrhoZVh+vjqqyY06Zph41KsGriU3xiikc8jxOoctlVNqKg/Dq3liTZ7
         X3RdUknVGBVqPjKFTk6PBG7QO5VnIZIJjOwi9LAhdv5Ud+MnXQC0xrSZmPQu3fdqk6Pd
         +kAyTkxzrbY8Oq/U5RUcxYDlC0BzXjbYa46foM8N7uIedAvpWxntCahSUnKvbBC4dliX
         JO+EQ12q79/srjgA98FjpyF0fF8b6cc5B2h6tOs9c+HGhP2Hip1+2kK8Y4fjj21jnMaS
         xj+H6p0RQl3iYvLsIV7c3lGHUJE0d1iV7QC3I7BODNbj0+HzWDePraPqq2azaeAKiGN/
         dctQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to:cc:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=psk3TBz1xhojOg0RjWkH/6eCV+DWe0tBZbt+Fttn+Q0=;
        b=RcV7pFj97pEktYgaUhqpACoKYGW+ZPUAE3B6KEsa+uRSqjqYhmrimBIQ0FvpD+BGIK
         1VheIA+RcAwiNaywsWqchrvhr0tyiWISJd9NyXQD+WsdRIAlt1OtGF/xbZGVtYEjgM7w
         cI/pd2FlEIKHGuKL59IBlcZJMcB6+qwVPePIParC/eFjra3vBmqa/bsG4tm3aEiwsRpJ
         gSw6HjtDKtK3/V8g8rsR6LAJ1P8HbqWocKQlh06EqGrPxRZKkP19fCbZN+Cc9k5r+mOc
         nKogKGgUKH0m+WoXCte5FTsu4lS4VpFAXzrs7Jz7AEya5PM6Kwo76/IvMHKde5yHNJA/
         qp8Q==
X-Gm-Message-State: AJaThX5zVQULJq9lxLKhPQw/IoK4h/sSdmcQroL0S1//OV495HJ4lofX
	Dtg1OEjIClYl6jXfAvawInoCBw==
X-Google-Smtp-Source: AGs4zMZOSHAoZGb2CL4qaUFOH3pclUwtJHbhFYgUgWzd2L1m0w6GG6GQIhQ0BG3nonWEVNP1seEaoQ==
X-Received: by 10.129.58.18 with SMTP id h18mr4158285ywa.74.1511283516495;
        Tue, 21 Nov 2017 08:58:36 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.129.125.133 with SMTP id y127ls119715ywc.18.gmail; Tue, 21 Nov
 2017 08:58:35 -0800 (PST)
X-Received: by 10.37.185.72 with SMTP id s8mr11144012ybm.444.1511283515290;
        Tue, 21 Nov 2017 08:58:35 -0800 (PST)
ARC-Seal: i=1; a=rsa-sha256; t=1511283515; cv=none;
        d=google.com; s=arc-20160816;
        b=KD7CakkqCWUGZWwKXz4B6RzM9zO1xbsymGOS7z3EfdxyknNVsoWHUzn1y4v89q5ZsP
         YGTKm2rC1qhq+F3ehoLz3kDWZV2oh2pRDPoyNTUiUkSoYW3QA8b7p8AralF2vX1glWwe
         XLVox2iRvi7YSZN6LlzBWWKJuvaugYjMMta6ItjaFR5EwIhgAtRbSwQptPZHouw9GwsN
         kMdFzriG5CrgAH5IXTHvGt2GcfCbmA5VK5IHTVT9cr/ezdwdpMSqUtP8tsfv9KHisEY2
         C3sbZ8JbVz1FsYGMYgMdcritvnvtJ9ddFwoNwzwqWUh+q7DEKlTebT9qzdkymXWhPCBZ
         jAbQ==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=cc:to:subject:message-id:date:from:references:in-reply-to
         :mime-version:dkim-signature:arc-authentication-results;
        bh=jwZT6ISCfD86m61nciT1S5OBdNIUAs47YPzur0PZgUE=;
        b=gND837iKpjPDFyW7as+zkVTGaQKqBwlNUHjLTMYZIEJNw3lBtG0oNsxiCH2kKx/o7v
         tMGqUy/ozy61UGN8oYmCvu9D1wFqjZY/wBkabeEzYRB40WBdJcun3Li/KpVc9FlxiIl7
         azJE2zGsqJnujXNy14EozokgI+kWG17O3t9T4xvuKhZBMaralUPbG7dkw7oGdRqYZUgI
         O9GL60uBSBXSmzIFMmSHwI9otIep1AmtaF24bUBLG3ZS4EqQp4z9VLwRw3yyYGHQaPri
         zLxbwkWKCK9K5bmBxzdjbIniIr9DOegCdthK2+AcMKP8GJ2IwPvaoe+XxQexuGZx24FF
         jW5Q==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@gmail.com header.s=20161025 header.b=l8Md6QOY;
       spf=pass (google.com: domain of james.a.cooper@gmail.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=james.a.cooper@gmail.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com
Original-Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65])
        by mx.google.com with SMTPS id v10sor4403278ybk.68.2017.11.21.08.58.35
        for <std-proposals@isocpp.org>
        (Google Transport Security);
        Tue, 21 Nov 2017 08:58:35 -0800 (PST)
Received-SPF: pass (google.com: domain of james.a.cooper@gmail.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65;
X-Received: by 10.37.100.7 with SMTP id y7mr10863266ybb.187.1511283514746;
 Tue, 21 Nov 2017 08:58:34 -0800 (PST)
Original-Received: by 10.37.183.200 with HTTP; Tue, 21 Nov 2017 08:58:34 -0800 (PST)
In-Reply-To: <bb14bcfe-f2fb-453e-834a-12e973d7ec57@isocpp.org>
X-Original-Sender: james.a.cooper@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com header.s=20161025 header.b=l8Md6QOY;       spf=pass
 (google.com: domain of james.a.cooper@gmail.com designates 209.85.220.65 as
 permitted sender) smtp.mailfrom=james.a.cooper@gmail.com;       dmarc=pass
 (p=NONE sp=NONE dis=NONE) header.from=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:35426
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/35426>

--089e082bdc600d44d1055e811d02
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tue, Nov 21, 2017 at 2:52 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

>
>
> On Tuesday, November 21, 2017 at 3:10:25 AM UTC-5, j c wrote:
>>
>>
>>
>> On Monday, November 20, 2017, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Monday, November 20, 2017 at 4:27:30 PM UTC-5, Bo Persson wrote:
>>>>
>>>> On 2017-11-20 19:30, Nicol Bolas wrote:
>>>> > On Monday, November 20, 2017 at 1:19:55 PM UTC-5, Bo Persson wrote:
>>>> >
>>>> >     On 2017-11-20 18:36, Aar=C3=B3n Bueno Villares wrote:
>>>> >      >
>>>> >      >
>>>> >      > On Monday, 20 November 2017 18:18:36 UTC+1, Nicol Bolas wrote=
:
>>>> >      >
>>>> >      >
>>>> >      >
>>>> >      >     On Monday, November 20, 2017 at 11:59:03 AM UTC-5, Aar=C3=
=B3n
>>>> Bueno
>>>> >      >     Villares wrote:
>>>> >      >
>>>> >      >         Enum classes doesn't allow, by default, implicit
>>>> >     conversion, not
>>>> >      >         even to the underlying type:
>>>> >      >
>>>> >      >         |
>>>> >      >         enumclassA :int{zero,one };
>>>> >      >         voidfoo(int){}
>>>> >      >
>>>> >      >         intmain(){foo(A::zero);}
>>>> >      >         |
>>>> >      >
>>>> >      >         and that is a good thing, but sometimes, you need a
>>>> enum
>>>> >     class
>>>> >      >         only to avoid name colissions, for example:
>>>> >      >
>>>> >      >         |
>>>> >      >         enumclasstable1_cols {id,name };
>>>> >      >         enumclasstable2_cols {id,address };
>>>> >      >         |
>>>> >      >
>>>> >      >         If table1_cols and table2_cols were raw enums, there
>>>> >     would be a
>>>> >      >         colission between both id named values, since they
>>>> have
>>>> >     global
>>>> >      >         namespace scope,
>>>> >      >
>>>> >      >
>>>> >      >     If they were unscoped enums, you could /still/ refer to
>>>> them as
>>>> >      >     `table1_cols::id` and `table2_cols::id`. So just do that.
>>>> >      >
>>>> >      >
>>>> >      > It gives you (g++ at least) a compiler error because `id` has
>>>> been
>>>> >      > redeclared.
>>>> >      >
>>>> >
>>>> >     So disable that warning, or put the unscoped enum inside its own
>>>> scope
>>>> >     (namespace or struct).
>>>> >
>>>> >     namespace table1_cols { enum {id,name}; };
>>>> >
>>>> >
>>>> > But then, it's difficult to use them as a typed quantity. That is,
>>>> > making a variable of type `table1_cols` isn't possible, since it's a
>>>> > namespace. You'd have to use `decltype` gymnastics.
>>>>
>>>> This was to solve one problem - implicit conversion to ints.
>>>>
>>>> If you want a type name for this, you can name the enum and use that a=
s
>>>> a type
>>>>
>>>>      namespace table1 { enum cols {id,name}; };
>>>>
>>>>      using table1_cols =3D table1::cols;
>>>>
>>>>
>>>> >
>>>> > Personally, I try to design things so that either we're talking abou=
t
>>>> an
>>>> > integer or we aren't. The OP's problem only arises when you have an
>>>> > enumeration that you sometimes use as an enum and sometimes use as a=
n
>>>> > integer. I don't think we should make language facilities to
>>>> facilitate
>>>> > that corner case; we should make it as painful as possible to
>>>> > /discourage/ design which leads to that.
>>>> >
>>>>
>>>> Yes, it is a problem when you use enum class to try to make the type
>>>> not
>>>> implicitly convertible to an integer, except sometimes. It is hard to
>>>> write the code for "implicitly convertible only when I want it to be".
>>>>
>>>
>>> I think the problem isn't that the values aren't implicitly convertible=
..
>>> It's that explicit conversion to the underlying type is a gigantic eyes=
ore.
>>> So... let's solve that problem: let's have a way to explicitly convert =
an
>>> enumerator to the underlying type, only without the verbosity of
>>> `static_cast`. A simple solution is to add an operator for that. Or rat=
her,
>>> use an existing operator for this, since this is totally not worth crea=
ting
>>> an operator for:
>>>
>>> enum class blah {...};
>>>
>>> auto operator+(blah b) {return static_cast<std::underlying_type_t<blah>
>>> >(b);}
>>>
>>> Then, when you want to convert an enumerator into the underlying type,
>>> you just use `+`. Granted, `+` may not be the best unary operator to us=
e
>>> here, but feel free to use whatever seems natural.
>>>
>>> You could even wrap such a definition in a macro, allowing it to be
>>> reused for any enumerator type you would like.
>>>
>>
>>
>> That won't be very helpful when you want to write an enum value to an
>> ostream (ambiguous overloads)
>> Want to write an enum to a binary file? You need to know the correct siz=
e.
>
>
> I don't know what you mean by "correct size", since pretty much any
> definition I could think of for that term would be spelled
> `std::underlying_type_t<enum_type>`.
>
> And there is exactly one overload of `operator+` here: the one that goes
> to `std::underlying_type_t`. So I fail to see how there can be "ambiguous
> overloads" from this code.
>
> Now, you could add new overloads for every enum you have, but hopefully w=
e
>> can all agree that that would be daft.
>>
>
> No, we can't. This is not a problem that crops up so frequently that it
> needs a solution. The conversion from enum to integer is not supposed to =
be
> a common operation, and there are many enumerations where that's simply
> unnecessary or are decidedly infrequent.
>
> This is a tool for the rarer enumerations where this kind of conversion
> *is* frequent. Type-safety should not be so lightly discarded.
>
> Not only that, the OP suggested being able to add something to an
> enumeration definition to make it implicitly convertible, with one idea
> being allowing the user to override the conversion operator within it. So
> it would be something you have to write for each enumeration you want to =
do
> this with.
>
> This `operator+` overload is essentially the same idea, only that you hav=
e
> to explicitly invoke it.
>
> The language needs to make this easy
>>
>
> No, it doesn't.
>
> Are there enumerations that are essentially integers-with-names, where
> you're frequently jumping back and forth between integer and enumeration?
> Yes. But that's not all or even most of them.
>
> So the language doesn't need to make this easy.
>
> --
> 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/bb14bcfe-f2fb-453e-
> 834a-12e973d7ec57%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bb14bcfe-f2=
fb-453e-834a-12e973d7ec57%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>


*> The conversion from enum to integer is not supposed to be a common
operation*

According to who? Enums aren't supposed to be printed or serialised? That's
news to me.
Why doesn't this code 'just work' when T is an enum?

std::ostream& operator<<(std::ostream& os, const T& value)
{
    os << value;
    return os;
}


*> Not only that, the OP suggested being able to add something to an
enumeration definition to make it implicitly convertible*

What else needs to be added?

enum class E : bool { ... }

The compiler already knows everything it needs, but chooses (at the moment)
to pretend it doesn't.


*> This is a tool for the rarer enumerations where this kind of conversion
is frequent. Type-safety should not be so lightly discarded.*

'Rarer' is entirely subjective. Totally agree on the type safety and so
nothing should be implicitly converted.
std::underlying_cast (don't worry about the actual name), if adopted, makes
it pretty clear to developers what's going on, far more so than an operator
would.
Then, the above code could be written as:

std::ostream& operator<<(std::ostream& os, const T& value)
{
    os << std::underlying_cast(value);
    return os;
}

This, in my opinion, would count as the language making something easy, as
much as that goes against the ethos of C++.

--=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/CAFQaeCBZXomwC%2BWK2rzg8VXi4EPz57Fo93fNh6w37oz7H=
gqehg%40mail.gmail.com.

--089e082bdc600d44d1055e811d02
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br></div><div class=3D"gma=
il_quote">On Tue, Nov 21, 2017 at 2:52 PM, Nicol Bolas <span dir=3D"ltr">&l=
t;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.=
com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);b=
order-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><br><br>On T=
uesday, November 21, 2017 at 3:10:25 AM UTC-5, j c wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-=
left-color:rgb(204,204,204);border-left-width:1px;border-left-style:solid">=
<br><br>On Monday, November 20, 2017, Nicol Bolas &lt;<a rel=3D"nofollow">j=
mck...@gmail.com</a>&gt; wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid"><div dir=3D"ltr">On Mo=
nday, November 20, 2017 at 4:27:30 PM UTC-5, Bo Persson wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;bor=
der-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:sol=
id">On 2017-11-20 19:30, Nicol Bolas wrote:
<br>&gt; On Monday, November 20, 2017 at 1:19:55 PM UTC-5, Bo Persson wrote=
:
<br>&gt;=20
<br>&gt; =C2=A0 =C2=A0 On 2017-11-20 18:36, Aar=C3=B3n Bueno Villares wrote=
:
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; On Monday, 20 November 2017 18:18:36 UTC+=
1, Nicol Bolas wrote:
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 On Monday, November 20, 201=
7 at 11:59:03 AM UTC-5, Aar=C3=B3n Bueno
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 Villares wrote:
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 Enum classes =
doesn&#39;t allow, by default, implicit
<br>&gt; =C2=A0 =C2=A0 conversion, not
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 even to the u=
nderlying type:
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 |
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 enumclassA :i=
nt{zero,one };
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 voidfoo(int){=
}
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 intmain(){foo=
(A::zero);}
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 |
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 and that is a=
 good thing, but sometimes, you need a enum
<br>&gt; =C2=A0 =C2=A0 class
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 only to avoid=
 name colissions, for example:
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 |
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 enumclasstabl=
e1_cols {id,name };
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 enumclasstabl=
e2_cols {id,address };
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 |
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 If table1_col=
s and table2_cols were raw enums, there
<br>&gt; =C2=A0 =C2=A0 would be a
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 colission bet=
ween both id named values, since they have
<br>&gt; =C2=A0 =C2=A0 global
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 namespace sco=
pe,
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 If they were unscoped enums=
, you could /still/ refer to them as
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; =C2=A0 =C2=A0 `table1_cols::id` and `tabl=
e2_cols::id`. So just do that.
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; It gives you (g++ at least) a compiler er=
ror because `id` has been
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt; redeclared.
<br>&gt; =C2=A0 =C2=A0 =C2=A0&gt;
<br>&gt;=20
<br>&gt; =C2=A0 =C2=A0 So disable that warning, or put the unscoped enum in=
side its own scope
<br>&gt; =C2=A0 =C2=A0 (namespace or struct).
<br>&gt;=20
<br>&gt; =C2=A0 =C2=A0 namespace table1_cols { enum {id,name}; };
<br>&gt;=20
<br>&gt;=20
<br>&gt; But then, it&#39;s difficult to use them as a typed quantity. That=
 is,=20
<br>&gt; making a variable of type `table1_cols` isn&#39;t possible, since =
it&#39;s a=20
<br>&gt; namespace. You&#39;d have to use `decltype` gymnastics.
<br>
<br>This was to solve one problem - implicit conversion to ints.
<br>
<br>If you want a type name for this, you can name the enum and use that as=
=20
<br>a type
<br>
<br>=C2=A0 =C2=A0 =C2=A0namespace table1 { enum cols {id,name}; };
<br>
<br>=C2=A0 =C2=A0 =C2=A0using table1_cols =3D table1::cols;
<br>
<br>
<br>&gt;=20
<br>&gt; Personally, I try to design things so that either we&#39;re talkin=
g about an=20
<br>&gt; integer or we aren&#39;t. The OP&#39;s problem only arises when yo=
u have an=20
<br>&gt; enumeration that you sometimes use as an enum and sometimes use as=
 an=20
<br>&gt; integer. I don&#39;t think we should make language facilities to f=
acilitate=20
<br>&gt; that corner case; we should make it as painful as possible to=20
<br>&gt; /discourage/ design which leads to that.
<br>&gt;
<br>
<br>Yes, it is a problem when you use enum class to try to make the type no=
t=20
<br>implicitly convertible to an integer, except sometimes. It is hard to=
=20
<br>write the code for &quot;implicitly convertible only when I want it to =
be&quot;.<br></blockquote><div><br></div><div>I think the problem isn&#39;t=
 that the values aren&#39;t implicitly convertible. It&#39;s that explicit =
conversion to the underlying type is a gigantic eyesore. So... let&#39;s so=
lve that problem: let&#39;s have a way to explicitly convert an enumerator =
to the underlying type, only without the verbosity of `static_cast`. A simp=
le solution is to add an operator for that. Or rather, use an existing oper=
ator for this, since this is totally not worth creating an operator for:<br=
></div><div><br></div><div style=3D"border:1px solid rgb(187,187,187);backg=
round-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)"=
>enum</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> blah </span><spa=
n style=3D"color:rgb(102,102,0)">{...};</span><span style=3D"color:rgb(0,0,=
0)"><br><br></span><span style=3D"color:rgb(0,0,136)">auto</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">operator<=
/span><span style=3D"color:rgb(102,102,0)">+(</span><span style=3D"color:rg=
b(0,0,0)">blah b</span><span style=3D"color:rgb(102,102,0)">)</span><span s=
tyle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</s=
pan><span style=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">static_cast</span><spa=
n style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)=
">std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"co=
lor:rgb(0,0,0)">underlying_ty<wbr>pe_t</span><span style=3D"color:rgb(0,136=
,0)">&lt;blah&gt;</span><span style=3D"color:rgb(102,102,0)">&gt;(</span><s=
pan style=3D"color:rgb(0,0,0)">b</span><span style=3D"color:rgb(102,102,0)"=
>);}</span></div></code></div><br>Then, when you want to convert an enumera=
tor into the underlying type, you just use `+`. Granted, `+` may not be the=
 best unary operator to use here, but feel free to use whatever seems natur=
al.<br><br>You could even wrap such a definition in a macro, allowing it to=
 be reused for any enumerator type you would like.<br></div></blockquote><d=
iv><br></div><div><br></div><div>That won&#39;t be very helpful when you wa=
nt to write an enum value to an ostream (ambiguous overloads)</div>Want to =
write an enum to a binary file? You need to know the correct size.</blockqu=
ote><div><br></div><div>I don&#39;t know what you mean by &quot;correct siz=
e&quot;, since pretty much any definition I could think of for that term wo=
uld be spelled `std::underlying_type_t&lt;enum_<wbr>type&gt;`.</div><div><b=
r></div><div>And there is exactly one overload of `operator+` here: the one=
 that goes to `std::underlying_type_t`. So I fail to see how there can be &=
quot;ambiguous overloads&quot; from this code.<br></div><div><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-lef=
t:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-=
style:solid"><div></div><div>Now, you could add new overloads for every enu=
m you have, but hopefully we can all agree that that would be daft.<br></di=
v></blockquote><div><br></div><div>No, we can&#39;t. This is not a problem =
that crops up so frequently that it needs a solution. The conversion from e=
num to integer is not supposed to be a common operation, and there are many=
 enumerations where that&#39;s simply unnecessary or are decidedly infreque=
nt.</div><div><br></div><div>This is a tool for the rarer enumerations wher=
e this kind of conversion <i>is</i> frequent. Type-safety should not be so =
lightly discarded.<br></div><div><br></div><div>Not only that, the OP sugge=
sted being able to add something to an enumeration definition to make it im=
plicitly convertible, with one idea being allowing the user to override the=
 conversion operator within it. So it would be something you have to write =
for each enumeration you want to do this with.</div><div><br></div><div>Thi=
s `operator+` overload is essentially the same idea, only that you have to =
explicitly invoke it.<br></div><div><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:r=
gb(204,204,204);border-left-width:1px;border-left-style:solid"><div><div>Th=
e language needs to make this easy</div></div></blockquote><div><br></div><=
div>No, it doesn&#39;t.</div><div><br></div><div>Are there enumerations tha=
t are essentially integers-with-names, where you&#39;re frequently jumping =
back and forth between integer and enumeration? Yes. But that&#39;s not all=
 or even most of them.</div><div><br></div><div>So the language doesn&#39;t=
 need to make this easy.<span class=3D"gmail-HOEnZb"><font color=3D"#888888=
"><br></font></span></div><span class=3D"gmail-HOEnZb"><font color=3D"#8888=
88"><br></font></span></div><span class=3D"gmail-HOEnZb"><font color=3D"#88=
8888">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bb14bcfe-f2fb-453e-834a-12e973d7ec57%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/bb14=
bcfe-f2fb-453e-<wbr>834a-12e973d7ec57%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><div><br></div><div><i></i><br></div><div>=
<i>&gt;=C2=A0The conversion from enum to integer is not supposed to be a co=
mmon operation</i></div><div><i></i><br></div><div>According to who? Enums =
aren&#39;t supposed to be printed or serialised? That&#39;s news to me.</di=
v><div>Why doesn&#39;t this code &#39;just work&#39; when T is an enum?</di=
v><div><br></div><div>std::ostream&amp; operator&lt;&lt;(std::ostream&amp; =
os, const T&amp; value)</div><div>{</div><div>=C2=A0 =C2=A0 os &lt;&lt; val=
ue;</div><div>=C2=A0 =C2=A0 return os;</div><div>}</div><div><br></div><div=
><br></div><div class=3D"gmail_extra"><b></b><u></u><sub></sub><sup></sup><=
strike></strike><i>&gt; Not only that, the OP suggested being able to add s=
omething to an enumeration definition to make it implicitly convertible</i>=
</div><div class=3D"gmail_extra"><i></i><br></div><div class=3D"gmail_extra=
">What else needs to be added?<br></div><div class=3D"gmail_extra"><br></di=
v><div class=3D"gmail_extra">enum class E : bool { ... }</div><div class=3D=
"gmail_extra"><br></div><div class=3D"gmail_extra">The compiler already kno=
ws everything it needs, but chooses (at the moment) to pretend it doesn&#39=
;t.</div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike><br></stri=
ke></div><div><br></div><div><i>&gt;=C2=A0This is a tool for the rarer enum=
erations where this kind of conversion is frequent. Type-safety should not =
be so lightly discarded.</i></div><div><i><br></i></div><div>&#39;Rarer&#39=
; is entirely subjective. Totally agree on the type safety and so nothing s=
hould be implicitly converted.</div><div>std::underlying_cast (don&#39;t wo=
rry about the actual name), if adopted, makes it pretty clear to developers=
 what&#39;s going on, far more so than an operator would.</div><div>Then, t=
he above code could be written as:</div><div><br></div><div><div>std::ostre=
am&amp; operator&lt;&lt;(std::ostream&amp; os, const T&amp; value)</div><di=
v>{</div><div>=C2=A0 =C2=A0 os &lt;&lt; std::underlying_cast(value);</div><=
div>=C2=A0 =C2=A0 return os;</div><div>}</div><div><br></div><div>This, in =
my opinion, would count as the language making something easy, as much as t=
hat goes against the ethos of C++.<br></div></div><div class=3D"gmail_extra=
"><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><b></b><i></i=
><u></u><sub></sub><sup></sup><strike></strike><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBZXomwC%2BWK2rzg8VXi4EPz57Fo93=
fNh6w37oz7Hgqehg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCBZXomwC%=
2BWK2rzg8VXi4EPz57Fo93fNh6w37oz7Hgqehg%40mail.gmail.com</a>.<br />

--089e082bdc600d44d1055e811d02--

.
