Topic: Proposal: type safe enums in parent scope


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 08 Jan 2014 14:07:06 -0500
Raw View
I really like the idea of type safe enums, however the mandatory scoping=20
causes two problems:

- It makes it much harder to switch over old code, since every use of=20
the enum must now be changed=B9.

- In some cases having to change the scope of the enum values may make=20
for a less optimal API.

- Work-arounds require either complicated preprocessor logic with=20
detrimental effects on code readability (assuming they can cover all=20
necessary cases, e.g. assigned values) or else repeating the list of=20
enum values; neither of which is desirable.

(=B9 In uncommon cases where the enum was already in a struct that existed=
=20
for no reason except to artificially scope the enum values, the new enum=20
class could simply replace the struct. I've not often seen this 'in the=20
wild' however.)


Regarding the second point, I have seen, and have in my own projects, a=20
number of cases where it is very logical for enum values to belong to=20
the scope of a class. For example, vtkAxis::TOP, QDialog::Accepted. Both=20
of these scopes are classes, with enums that either describe an instance=20
of the class or relate intimately to the use of the class. It's=20
difficult to come up with a name for an enum that would be "more natural=20
to write" as the value scope than the class name is currently.


Given the above, I'd like to propose that the 'inline' keyword be=20
extended to 'enum class'. For example:

class Foo
{
public:
   inline enum class Bar
   {
     A,
     B,
     ...
   };
   ...
};


The effect of this, similar to 'inline namespace', is to make the enum=20
values accessible to the parent scope ('Foo', in the above example),=20
without otherwise changing the semantics of 'enum class' (i.e. it is=20
still type safe, values can still be named like 'Foo::Bar::A', etc.).

This would address both above points with hopefully minimal changes to=20
compilers (which already must support these scope rules for non-typesafe=20
enums).

Feedback?

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 8 Jan 2014 13:11:15 -0800
Raw View
--047d7b6d857af15d8404ef7bee12
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Wed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke <
mw_triad@users.sourceforge.net> wrote:

> I really like the idea of type safe enums, however the mandatory scoping
> causes two problems:
>
> - It makes it much harder to switch over old code, since every use of the
> enum must now be changed=B9.
>
> - In some cases having to change the scope of the enum values may make fo=
r
> a less optimal API.
>
> - Work-arounds require either complicated preprocessor logic with
> detrimental effects on code readability (assuming they can cover all
> necessary cases, e.g. assigned values) or else repeating the list of enum
> values; neither of which is desirable.
>
> (=B9 In uncommon cases where the enum was already in a struct that existe=
d
> for no reason except to artificially scope the enum values, the new enum
> class could simply replace the struct. I've not often seen this 'in the
> wild' however.)
>
>
> Regarding the second point, I have seen, and have in my own projects, a
> number of cases where it is very logical for enum values to belong to the
> scope of a class. For example, vtkAxis::TOP, QDialog::Accepted. Both of
> these scopes are classes, with enums that either describe an instance of
> the class or relate intimately to the use of the class. It's difficult to
> come up with a name for an enum that would be "more natural to write" as
> the value scope than the class name is currently.
>
>
> Given the above, I'd like to propose that the 'inline' keyword be extende=
d
> to 'enum class'. For example:
>
> class Foo
> {
> public:
>   inline enum class Bar
>   {
>     A,
>     B,
>     ...
>   };
>   ...
> };
>
>
> The effect of this, similar to 'inline namespace', is to make the enum
> values accessible to the parent scope ('Foo', in the above example),
> without otherwise changing the semantics of 'enum class' (i.e. it is stil=
l
> type safe, values can still be named like 'Foo::Bar::A', etc.).
>
> This would address both above points with hopefully minimal changes to
> compilers (which already must support these scope rules for non-typesafe
> enums).
>
> Feedback?


There are other cases where similar functionality is desirable:

namespace A {
  enum E { e1, e2 };
}

namespace B {
  // Want to include E and all of its enumerators here
  using A::E;
  using A::e1;
  using A::e2;
  // ...
}

Both use cases can be addressed by a different syntax:

namespace B {
  using A::E;
  using enum E;
}

class Foo {
public:
  enum class Bar { A, B, ... };
  using enum Bar;
  ...
};

The idea would be that "using enum E;" works somewhat like "using namespace
N;". Specifically, each enumerator in E would become visible in the scope
containing the directive.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--047d7b6d857af15d8404ef7bee12
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mw_triad@users.sourceforge.net" target=3D"_blank">mw_triad@users=
..sourceforge.net</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">I really like the idea of type safe enums, h=
owever the mandatory scoping causes two problems:<br>
<br>
- It makes it much harder to switch over old code, since every use of the e=
num must now be changed=B9.<br>
<br>
- In some cases having to change the scope of the enum values may make for =
a less optimal API.<br>
<br>
- Work-arounds require either complicated preprocessor logic with detriment=
al effects on code readability (assuming they can cover all necessary cases=
, e.g. assigned values) or else repeating the list of enum values; neither =
of which is desirable.<br>

<br>
(=B9 In uncommon cases where the enum was already in a struct that existed =
for no reason except to artificially scope the enum values, the new enum cl=
ass could simply replace the struct. I&#39;ve not often seen this &#39;in t=
he wild&#39; however.)<br>

<br>
<br>
Regarding the second point, I have seen, and have in my own projects, a num=
ber of cases where it is very logical for enum values to belong to the scop=
e of a class. For example, vtkAxis::TOP, QDialog::Accepted. Both of these s=
copes are classes, with enums that either describe an instance of the class=
 or relate intimately to the use of the class. It&#39;s difficult to come u=
p with a name for an enum that would be &quot;more natural to write&quot; a=
s the value scope than the class name is currently.<br>

<br>
<br>
Given the above, I&#39;d like to propose that the &#39;inline&#39; keyword =
be extended to &#39;enum class&#39;. For example:<br>
<br>
class Foo<br>
{<br>
public:<br>
=A0 inline enum class Bar<br>
=A0 {<br>
=A0 =A0 A,<br>
=A0 =A0 B,<br>
=A0 =A0 ...<br>
=A0 };<br>
=A0 ...<br>
};<br>
<br>
<br>
The effect of this, similar to &#39;inline namespace&#39;, is to make the e=
num values accessible to the parent scope (&#39;Foo&#39;, in the above exam=
ple), without otherwise changing the semantics of &#39;enum class&#39; (i.e=
.. it is still type safe, values can still be named like &#39;Foo::Bar::A&#3=
9;, etc.).<br>

<br>
This would address both above points with hopefully minimal changes to comp=
ilers (which already must support these scope rules for non-typesafe enums)=
..<br>
<br>
Feedback?</blockquote><div><br></div><div>There are other cases where simil=
ar functionality is desirable:</div><div><br></div><div>namespace A {</div>=
<div>=A0 enum E { e1, e2 };</div><div>}</div><div><br></div><div>namespace =
B {</div>
<div>=A0 // Want to include E and all of its enumerators here</div><div>=A0=
 using A::E;</div><div>=A0 using A::e1;</div><div>=A0 using A::e2;</div><di=
v>=A0 // ...</div><div>}</div><div><br></div><div>Both use cases can be add=
ressed by a different syntax:</div>
<div><br></div><div>namespace B {</div><div>=A0 using A::E;</div><div>=A0 u=
sing enum E;</div><div>}</div><div><br></div><div>class Foo {</div><div>pub=
lic:</div><div>=A0 enum class Bar { A, B, ... };</div><div>=A0 using enum B=
ar;</div>
<div>=A0 ...</div><div>};</div><div><br></div><div>The idea would be that &=
quot;using enum E;&quot; works somewhat like &quot;using namespace N;&quot;=
.. Specifically, each enumerator in E would become visible in the scope cont=
aining the directive.</div>
</div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b6d857af15d8404ef7bee12--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 08 Jan 2014 16:33:23 -0500
Raw View
On 2014-01-08 16:11, Richard Smith wrote:
> On Wed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke wrote:
>> I really like the idea of type safe enums, however the mandatory scoping
>> causes two problems:
>>  [snipped]
>>
>> Given the above, I'd like to propose that the 'inline' keyword be extended
>> to 'enum class'. [example snipped]
>>
>> The effect of this, similar to 'inline namespace', is to make the enum
>> values accessible to the parent scope ('Foo', in the above example),
>> without otherwise changing the semantics of 'enum class' (i.e. it is still
>> type safe, values can still be named like 'Foo::Bar::A', etc.).
>
> There are other cases where similar functionality is desirable:
>
> namespace A {
>    enum E { e1, e2 };
> }
>
> namespace B {
>    // Want to include E and all of its enumerators here
>    using A::E;
>    using A::e1;
>    using A::e2;
>    // ...
> }
>
> Both use cases can be addressed by a different syntax:
>
> namespace B {
>    using A::E;
>    using enum E;
> }
>
> class Foo {
> public:
>    enum class Bar { A, B, ... };
>    using enum Bar;
>    ...
> };
>
> The idea would be that "using enum E;" works somewhat like "using namespace
> N;". Specifically, each enumerator in E would become visible in the scope
> containing the directive.

That syntax is very similar to e.g. 'using Bar', but has rather
different effect (introducing more than the named symbol into the
scope). But I guess this is true for 'using namespace' also.

(Another possible argument against is that yours introducing a new form
of copying symbols from one scope to another, which might be more effort
to implement.)

TBH I am on the fence; both I think have points to their favor and I
would be amenable to either solution and am disinclined to prefer one
over the other. Do others have a preference?

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Wed, 8 Jan 2014 14:42:45 -0800 (PST)
Raw View
------=_Part_727_14131058.1389220965315
Content-Type: text/plain; charset=ISO-8859-1

Correct me if I'm wrong but I think that your use of "using enum" is not
really consistent with if you placed a "using namespace" in the same source
code position.

What was asked for was a mechanism to make the enumerators available with
(from your example) Foo:A and Foo::B outside the Foo class head.

But if you had written using namespace <namespace>; in this position the
names of that namespace would not have been available as
Foo::<namespace-member> after the Foo class head...

Thus the usage of using is limping.

As for the original suggestion I feel that it is a pity that you would have
to write three keywords "inline enum class" to get something that is
halfways betwen a old enum and a new enum class. Maybe just enum inline {
.... }; would work, taking the view that "new style enums are either scoped
using enum class or unscoped using enum inline, while both of them have the
new property of not being implicitly convertible to/from numeric types."

Den onsdagen den 8:e januari 2014 kl. 22:33:23 UTC+1 skrev Matthew Woehlke:
>
> On 2014-01-08 16:11, Richard Smith wrote:
> > On Wed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke wrote:
> >> I really like the idea of type safe enums, however the mandatory
> scoping
> >> causes two problems:
> >>  [snipped]
> >>
> >> Given the above, I'd like to propose that the 'inline' keyword be
> extended
> >> to 'enum class'. [example snipped]
> >>
> >> The effect of this, similar to 'inline namespace', is to make the enum
> >> values accessible to the parent scope ('Foo', in the above example),
> >> without otherwise changing the semantics of 'enum class' (i.e. it is
> still
> >> type safe, values can still be named like 'Foo::Bar::A', etc.).
> >
> > There are other cases where similar functionality is desirable:
> >
> > namespace A {
> >    enum E { e1, e2 };
> > }
> >
> > namespace B {
> >    // Want to include E and all of its enumerators here
> >    using A::E;
> >    using A::e1;
> >    using A::e2;
> >    // ...
> > }
> >
> > Both use cases can be addressed by a different syntax:
> >
> > namespace B {
> >    using A::E;
> >    using enum E;
> > }
> >
> > class Foo {
> > public:
> >    enum class Bar { A, B, ... };
> >    using enum Bar;
> >    ...
> > };
> >
> > The idea would be that "using enum E;" works somewhat like "using
> namespace
> > N;". Specifically, each enumerator in E would become visible in the
> scope
> > containing the directive.
>
> That syntax is very similar to e.g. 'using Bar', but has rather
> different effect (introducing more than the named symbol into the
> scope). But I guess this is true for 'using namespace' also.
>
> (Another possible argument against is that yours introducing a new form
> of copying symbols from one scope to another, which might be more effort
> to implement.)
>
> TBH I am on the fence; both I think have points to their favor and I
> would be amenable to either solution and am disinclined to prefer one
> over the other. Do others have a preference?
>
> --
> Matthew
>
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_727_14131058.1389220965315
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Correct me if I'm wrong but I think that your use of "usin=
g enum" is not really consistent with if you placed a "using namespace" in =
the same source code position.<div><br></div><div>What was asked for was a =
mechanism to make the enumerators available with (from your example) Foo:A =
and Foo::B outside the Foo class head.</div><div><br></div><div>But if you =
had written using namespace &lt;namespace&gt;; in this position the names o=
f that namespace would not have been available as Foo::&lt;namespace-member=
&gt; after the Foo class head...</div><div><br></div><div>Thus the usage of=
 using is limping.</div><div><br></div><div>As for the original suggestion =
I feel that it is a pity that you would have to write three keywords "inlin=
e enum class" to get something that is halfways betwen a old enum and a new=
 enum class. Maybe just enum inline { ... }; would work, taking the view th=
at "new style enums are either scoped using enum class or unscoped using en=
um inline, while both of them have the new property of not being implicitly=
 convertible to/from numeric types."</div><br>Den onsdagen den 8:e januari =
2014 kl. 22:33:23 UTC+1 skrev Matthew Woehlke:<blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;">On 2014-01-08 16:11, Richard Smith wrote:
<br>&gt; On Wed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke wrote:
<br>&gt;&gt; I really like the idea of type safe enums, however the mandato=
ry scoping
<br>&gt;&gt; causes two problems:
<br>&gt;&gt; &nbsp;[snipped]
<br>&gt;&gt;
<br>&gt;&gt; Given the above, I'd like to propose that the 'inline' keyword=
 be extended
<br>&gt;&gt; to 'enum class'. [example snipped]
<br>&gt;&gt;
<br>&gt;&gt; The effect of this, similar to 'inline namespace', is to make =
the enum
<br>&gt;&gt; values accessible to the parent scope ('Foo', in the above exa=
mple),
<br>&gt;&gt; without otherwise changing the semantics of 'enum class' (i.e.=
 it is still
<br>&gt;&gt; type safe, values can still be named like 'Foo::Bar::A', etc.)=
..
<br>&gt;
<br>&gt; There are other cases where similar functionality is desirable:
<br>&gt;
<br>&gt; namespace A {
<br>&gt; &nbsp; &nbsp;enum E { e1, e2 };
<br>&gt; }
<br>&gt;
<br>&gt; namespace B {
<br>&gt; &nbsp; &nbsp;// Want to include E and all of its enumerators here
<br>&gt; &nbsp; &nbsp;using A::E;
<br>&gt; &nbsp; &nbsp;using A::e1;
<br>&gt; &nbsp; &nbsp;using A::e2;
<br>&gt; &nbsp; &nbsp;// ...
<br>&gt; }
<br>&gt;
<br>&gt; Both use cases can be addressed by a different syntax:
<br>&gt;
<br>&gt; namespace B {
<br>&gt; &nbsp; &nbsp;using A::E;
<br>&gt; &nbsp; &nbsp;using enum E;
<br>&gt; }
<br>&gt;
<br>&gt; class Foo {
<br>&gt; public:
<br>&gt; &nbsp; &nbsp;enum class Bar { A, B, ... };
<br>&gt; &nbsp; &nbsp;using enum Bar;
<br>&gt; &nbsp; &nbsp;...
<br>&gt; };
<br>&gt;
<br>&gt; The idea would be that "using enum E;" works somewhat like "using =
namespace
<br>&gt; N;". Specifically, each enumerator in E would become visible in th=
e scope
<br>&gt; containing the directive.
<br>
<br>That syntax is very similar to e.g. 'using Bar', but has rather=20
<br>different effect (introducing more than the named symbol into the=20
<br>scope). But I guess this is true for 'using namespace' also.
<br>
<br>(Another possible argument against is that yours introducing a new form=
=20
<br>of copying symbols from one scope to another, which might be more effor=
t=20
<br>to implement.)
<br>
<br>TBH I am on the fence; both I think have points to their favor and I=20
<br>would be amenable to either solution and am disinclined to prefer one=
=20
<br>over the other. Do others have a preference?
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_727_14131058.1389220965315--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 09 Jan 2014 07:40:26 +0800
Raw View
On 1/9/14 5:11 AM, Richard Smith wrote:
> There are other cases where similar functionality is desirable:
>
> namespace A {
>    enum E { e1, e2 };
> }
>
> namespace B {
>    // Want to include E and all of its enumerators here
>    using A::E;
>    using A::e1;
>    using A::e2;
>    // ...
> }
>
> Both use cases can be addressed by a different syntax:
>
> namespace B {
>    using A::E;
>    using enum E;
> }
>
> class Foo {
> public:
>    enum class Bar { A, B, ... };
>    using enum Bar;
>    ...
> };
>
> The idea would be that "using enum E;" works somewhat like "using namespace
> N;". Specifically, each enumerator in E would become visible in the scope
> containing the directive.

But "enum E" is already an elaborated-type-specifier. If you add a
nested-name-specifier, it already matches the existing using declaration
syntax. So this idea works as long as you're OK with requiring the enum
type to be accessible unqualified from the target scope before its
enumerators are.

namespace B {
   using enum A::E; // OK, now name E has unqualified access.
   using enum E; // OK, use unqualified access to import enumerators.
}


Which is reasonable, I suppose, but the distinction is a bit confusing.
Also, the prohibition on being able to import a namespace scope type
name into class scope should probably be relaxed, because the two use
cases you mention aren't mutually exclusive.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 8 Jan 2014 16:31:47 -0800
Raw View
--001a1133c66c16200a04ef7ebcdf
Content-Type: text/plain; charset=ISO-8859-1

On Wed, Jan 8, 2014 at 3:40 PM, David Krauss <potswa@gmail.com> wrote:

> On 1/9/14 5:11 AM, Richard Smith wrote:
>
>> There are other cases where similar functionality is desirable:
>>
>> namespace A {
>>    enum E { e1, e2 };
>> }
>>
>> namespace B {
>>    // Want to include E and all of its enumerators here
>>    using A::E;
>>    using A::e1;
>>    using A::e2;
>>    // ...
>> }
>>
>> Both use cases can be addressed by a different syntax:
>>
>> namespace B {
>>    using A::E;
>>    using enum E;
>> }
>>
>> class Foo {
>> public:
>>    enum class Bar { A, B, ... };
>>    using enum Bar;
>>    ...
>> };
>>
>> The idea would be that "using enum E;" works somewhat like "using
>> namespace
>> N;". Specifically, each enumerator in E would become visible in the scope
>> containing the directive.
>>
>
> But "enum E" is already an elaborated-type-specifier. If you add a
> nested-name-specifier, it already matches the existing using declaration
> syntax.


That's not correct: a using-declaration requires an unqualified-id or
(effectively) a qualified-id. It does not accept an
elaborated-type-specifier.


> So this idea works as long as you're OK with requiring the enum type to be
> accessible unqualified from the target scope before its enumerators are.
>
> namespace B {
>   using enum A::E; // OK, now name E has unqualified access.
>   using enum E; // OK, use unqualified access to import enumerators.
> }
>
>
> Which is reasonable, I suppose, but the distinction is a bit confusing.
> Also, the prohibition on being able to import a namespace scope type name
> into class scope should probably be relaxed, because the two use cases you
> mention aren't mutually exclusive.
>
>
> --
>
> --- 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.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-
> proposals/.
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a1133c66c16200a04ef7ebcdf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Jan 8, 2014 at 3:40 PM, David Krauss <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:potswa@gmail.com" target=3D"_blank">potswa@gmail.com</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div class=3D"im">On 1/9/14 5:11 AM, Richard=
 Smith wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">
There are other cases where similar functionality is desirable:<br>
<br>
namespace A {<br>
=A0 =A0enum E { e1, e2 };<br>
}<br>
<br>
namespace B {<br>
=A0 =A0// Want to include E and all of its enumerators here<br>
=A0 =A0using A::E;<br>
=A0 =A0using A::e1;<br>
=A0 =A0using A::e2;<br>
=A0 =A0// ...<br>
}<br>
<br>
Both use cases can be addressed by a different syntax:<br>
<br>
namespace B {<br>
=A0 =A0using A::E;<br>
=A0 =A0using enum E;<br>
}<br>
<br>
class Foo {<br>
public:<br>
=A0 =A0enum class Bar { A, B, ... };<br>
=A0 =A0using enum Bar;<br>
=A0 =A0...<br>
};<br>
<br>
The idea would be that &quot;using enum E;&quot; works somewhat like &quot;=
using namespace<br>
N;&quot;. Specifically, each enumerator in E would become visible in the sc=
ope<br>
containing the directive.<br>
</blockquote>
<br></div>
But &quot;enum E&quot; is already an elaborated-type-specifier. If you add =
a nested-name-specifier, it already matches the existing using declaration =
syntax.</blockquote><div><br></div><div>That&#39;s not correct: a using-dec=
laration requires an unqualified-id or (effectively) a qualified-id. It doe=
s not accept an elaborated-type-specifier.</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"> So this idea works as long as=
 you&#39;re OK with requiring the enum type to be accessible unqualified fr=
om the target scope before its enumerators are.<br>

<br>
namespace B {<br>
=A0 using enum A::E; // OK, now name E has unqualified access.<br>
=A0 using enum E; // OK, use unqualified access to import enumerators.<br>
}<br>
<br>
<br>
Which is reasonable, I suppose, but the distinction is a bit confusing. Als=
o, the prohibition on being able to import a namespace scope type name into=
 class scope should probably be relaxed, because the two use cases you ment=
ion aren&#39;t mutually exclusive.<div class=3D"HOEnZb">
<div class=3D"h5"><br>
<br>
-- <br>
<br>
--- You received this message because you are subscribed to the Google Grou=
ps &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%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@<u></u>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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<u></u>isocpp.=
org/group/std-<u></u>proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1133c66c16200a04ef7ebcdf--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 8 Jan 2014 16:37:34 -0800
Raw View
--089e0111c2dcca657704ef7ed0fe
Content-Type: text/plain; charset=ISO-8859-1

On Wed, Jan 8, 2014 at 2:42 PM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> Correct me if I'm wrong but I think that your use of "using enum" is not
> really consistent with if you placed a "using namespace" in the same source
> code position.
>
> What was asked for was a mechanism to make the enumerators available with
> (from your example) Foo:A and Foo::B outside the Foo class head.
>
> But if you had written using namespace <namespace>; in this position the
> names of that namespace would not have been available as
> Foo::<namespace-member> after the Foo class head...
>

It's true that you can't put a using-directive in a class scope. But I
think you're saying that this doesn't work:

namespace A {
  int n;
}
namespace B {
  using namespace A;
}
int k = B::n;

The above *does* work. By analogy:

enum A {
  n
};
struct B {
  using enum A;
};
A k = B::n;

.... would also work, under my suggestion.

There is a subtle distinction between 'using namespace' and 'using enum' as
I've proposed it so far, and that's that using-directives have a somewhat
subtle behavior when performing unqualified lookup: the using-directive
puts the names in the lowest common ancestor of the nominating namespace
and the nominated namespace, rather than directly in the nominating
namespace, for the purpose of unqualified lookup (to avoid additions to the
nominated namespace changing the behavior of distant code that's not aware
of the addition). I'm on the fence as to whether 'using enum' should
inherit this behavior.

Thus the usage of using is limping.
>
> As for the original suggestion I feel that it is a pity that you would
> have to write three keywords "inline enum class" to get something that is
> halfways betwen a old enum and a new enum class. Maybe just enum inline {
> ... }; would work, taking the view that "new style enums are either scoped
> using enum class or unscoped using enum inline, while both of them have the
> new property of not being implicitly convertible to/from numeric types."
>
> Den onsdagen den 8:e januari 2014 kl. 22:33:23 UTC+1 skrev Matthew Woehlke:
>
>> On 2014-01-08 16:11, Richard Smith wrote:
>> > On Wed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke wrote:
>> >> I really like the idea of type safe enums, however the mandatory
>> scoping
>> >> causes two problems:
>> >>  [snipped]
>> >>
>> >> Given the above, I'd like to propose that the 'inline' keyword be
>> extended
>> >> to 'enum class'. [example snipped]
>> >>
>> >> The effect of this, similar to 'inline namespace', is to make the enum
>> >> values accessible to the parent scope ('Foo', in the above example),
>> >> without otherwise changing the semantics of 'enum class' (i.e. it is
>> still
>> >> type safe, values can still be named like 'Foo::Bar::A', etc.).
>> >
>> > There are other cases where similar functionality is desirable:
>> >
>> > namespace A {
>> >    enum E { e1, e2 };
>> > }
>> >
>> > namespace B {
>> >    // Want to include E and all of its enumerators here
>> >    using A::E;
>> >    using A::e1;
>> >    using A::e2;
>> >    // ...
>> > }
>> >
>> > Both use cases can be addressed by a different syntax:
>> >
>> > namespace B {
>> >    using A::E;
>> >    using enum E;
>> > }
>> >
>> > class Foo {
>> > public:
>> >    enum class Bar { A, B, ... };
>> >    using enum Bar;
>> >    ...
>> > };
>> >
>> > The idea would be that "using enum E;" works somewhat like "using
>> namespace
>> > N;". Specifically, each enumerator in E would become visible in the
>> scope
>> > containing the directive.
>>
>> That syntax is very similar to e.g. 'using Bar', but has rather
>> different effect (introducing more than the named symbol into the
>> scope). But I guess this is true for 'using namespace' also.
>>
>> (Another possible argument against is that yours introducing a new form
>> of copying symbols from one scope to another, which might be more effort
>> to implement.)
>>
>> TBH I am on the fence; both I think have points to their favor and I
>> would be amenable to either solution and am disinclined to prefer one
>> over the other. Do others have a preference?
>>
>> --
>> Matthew
>>
>>  --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--089e0111c2dcca657704ef7ed0fe
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Jan 8, 2014 at 2:42 PM, Bengt Gustafsson <span dir=3D"ltr">&lt;<a href=
=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafsso=
n@beamways.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Correct me if I&#39;m wrong=
 but I think that your use of &quot;using enum&quot; is not really consiste=
nt with if you placed a &quot;using namespace&quot; in the same source code=
 position.<div>
<br></div><div>What was asked for was a mechanism to make the enumerators a=
vailable with (from your example) Foo:A and Foo::B outside the Foo class he=
ad.</div><div><br></div><div>But if you had written using namespace &lt;nam=
espace&gt;; in this position the names of that namespace would not have bee=
n available as Foo::&lt;namespace-member&gt; after the Foo class head...</d=
iv>
</div></blockquote><div><br></div><div>It&#39;s true that you can&#39;t put=
 a using-directive in a class scope. But I think you&#39;re saying that thi=
s doesn&#39;t work:</div><div><br></div><div>namespace A {</div><div>=A0 in=
t n;</div>
<div>}</div><div>namespace B {</div><div>=A0 using namespace A;</div><div>}=
</div><div>int k =3D B::n;</div><div><br></div><div>The above *does* work. =
By analogy:</div><div><br></div><div>enum A {</div><div>=A0 n</div><div>};<=
/div>
<div>struct B {</div><div>=A0 using enum A;</div><div>};</div><div>A k =3D =
B::n;</div><div><br></div><div>... would also work, under my suggestion.</d=
iv><div><br></div><div>There is a subtle distinction between &#39;using nam=
espace&#39; and &#39;using enum&#39; as I&#39;ve proposed it so far, and th=
at&#39;s that using-directives have a somewhat subtle behavior when perform=
ing unqualified lookup: the using-directive puts the names in the lowest co=
mmon ancestor of the nominating namespace and the nominated namespace, rath=
er than directly in the nominating namespace, for the purpose of unqualifie=
d lookup (to avoid additions to the nominated namespace changing the behavi=
or of distant code that&#39;s not aware of the addition). I&#39;m on the fe=
nce as to whether &#39;using enum&#39; should inherit this behavior.</div>
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Thus th=
e usage of using is limping.</div><div><br></div><div>As for the original s=
uggestion I feel that it is a pity that you would have to write three keywo=
rds &quot;inline enum class&quot; to get something that is halfways betwen =
a old enum and a new enum class. Maybe just enum inline { ... }; would work=
, taking the view that &quot;new style enums are either scoped using enum c=
lass or unscoped using enum inline, while both of them have the new propert=
y of not being implicitly convertible to/from numeric types.&quot;</div>
<br>Den onsdagen den 8:e januari 2014 kl. 22:33:23 UTC+1 skrev Matthew Woeh=
lke:<div><div class=3D"h5"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 2014-=
01-08 16:11, Richard Smith wrote:
<br>&gt; On Wed, Jan 8, 2014 at 11:07 AM, Matthew Woehlke wrote:
<br>&gt;&gt; I really like the idea of type safe enums, however the mandato=
ry scoping
<br>&gt;&gt; causes two problems:
<br>&gt;&gt; =A0[snipped]
<br>&gt;&gt;
<br>&gt;&gt; Given the above, I&#39;d like to propose that the &#39;inline&=
#39; keyword be extended
<br>&gt;&gt; to &#39;enum class&#39;. [example snipped]
<br>&gt;&gt;
<br>&gt;&gt; The effect of this, similar to &#39;inline namespace&#39;, is =
to make the enum
<br>&gt;&gt; values accessible to the parent scope (&#39;Foo&#39;, in the a=
bove example),
<br>&gt;&gt; without otherwise changing the semantics of &#39;enum class&#3=
9; (i.e. it is still
<br>&gt;&gt; type safe, values can still be named like &#39;Foo::Bar::A&#39=
;, etc.).
<br>&gt;
<br>&gt; There are other cases where similar functionality is desirable:
<br>&gt;
<br>&gt; namespace A {
<br>&gt; =A0 =A0enum E { e1, e2 };
<br>&gt; }
<br>&gt;
<br>&gt; namespace B {
<br>&gt; =A0 =A0// Want to include E and all of its enumerators here
<br>&gt; =A0 =A0using A::E;
<br>&gt; =A0 =A0using A::e1;
<br>&gt; =A0 =A0using A::e2;
<br>&gt; =A0 =A0// ...
<br>&gt; }
<br>&gt;
<br>&gt; Both use cases can be addressed by a different syntax:
<br>&gt;
<br>&gt; namespace B {
<br>&gt; =A0 =A0using A::E;
<br>&gt; =A0 =A0using enum E;
<br>&gt; }
<br>&gt;
<br>&gt; class Foo {
<br>&gt; public:
<br>&gt; =A0 =A0enum class Bar { A, B, ... };
<br>&gt; =A0 =A0using enum Bar;
<br>&gt; =A0 =A0...
<br>&gt; };
<br>&gt;
<br>&gt; The idea would be that &quot;using enum E;&quot; works somewhat li=
ke &quot;using namespace
<br>&gt; N;&quot;. Specifically, each enumerator in E would become visible =
in the scope
<br>&gt; containing the directive.
<br>
<br>That syntax is very similar to e.g. &#39;using Bar&#39;, but has rather=
=20
<br>different effect (introducing more than the named symbol into the=20
<br>scope). But I guess this is true for &#39;using namespace&#39; also.
<br>
<br>(Another possible argument against is that yours introducing a new form=
=20
<br>of copying symbols from one scope to another, which might be more effor=
t=20
<br>to implement.)
<br>
<br>TBH I am on the fence; both I think have points to their favor and I=20
<br>would be amenable to either solution and am disinclined to prefer one=
=20
<br>over the other. Do others have a preference?
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div></div></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
=A0<br>
--- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0111c2dcca657704ef7ed0fe--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 10 Jan 2014 16:07:52 -0500
Raw View
On 2014-01-08 17:42, Bengt Gustafsson wrote:
> As for the original suggestion I feel that it is a pity that you would have
> to write three keywords "inline enum class" to get something that is
> halfways betwen a old enum and a new enum class. Maybe just enum inline {
> ... }; would work, taking the view that "new style enums are either scoped
> using enum class or unscoped using enum inline, while both of them have the
> new property of not being implicitly convertible to/from numeric types."

While I get where you're coming from, this feels to me like the
semantics would be confusing.

I would rather continue, as now, to say that "enum" is an old-style
enumeration and "enum class" is a new style, period. Thus, "inline enum
{...}" should be allowed (the 'inline' here would be redundant, unless
compilers were to add e.g. a '-fno-implicit-inline-enum' option), and
would refer to an old-style enumeration. Especially as C++11 allows
qualifying the values even where not necessary to do so. This way the
scoping and type-safety properties are kept closer to orthogonal.


I remain inclined to start with 'inline enum [class]' rather than 'using
enum', as it represents the least amount of work for compilers and the
least semantic change, essentially "bringing back" a feature that was
lost with 'enum class' as opposed to implementing entirely new features.

(As an extension, I would suggest 'using B = inline A' to import the
values of an enum into another scope, if others feel strongly that that
is important. However we couldn't do that before C++11 either...)

--
Matthew

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.