4

A point from N3290 draft ISO Standard, §3.4.1/12:

During the lookup of a name used in the constant-expression of an enumerator-definition, previously declared enumerators of the enumeration are visible and hide the names of entities declared in the block, class, or namespace scopes containing the enum-specifier.

This is the added new point, can any one explain this..point with an example (in terms of an example) please?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
user767856
  • 75
  • 3

1 Answers1

10

Let's just have some code:

struct X {};

enum Foo
{
  X = 0,
  Y,
  Z = X // X refers to the enum, not the type
};
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 1
    `Z = X + n` would be best since two enum members cannot have the same value. – neodelphi May 25 '11 at 06:31
  • 4
    @neodelphi: actually... they can. For example it's not uncommon that several different errors map to the same error code, in which case there are one "member" for each error, but less values than members. – Matthieu M. May 25 '11 at 06:38
  • 1
    Other common-enough examples: `{ MIN = 4, A = 4, B, C, D, MAX = D }`, `{ CASE_INSENSITIVE = 0, CASE_SENSITIVE = 1, NO_SUBEXPR_CAPTURE = 0, SUBEXPR_CAPTURE = 2 }`... – Tony Delroy May 25 '11 at 06:49
  • @Tony : what actually meant for SUBEXPR_CAPTURE in the above example – user767856 May 25 '11 at 11:40
  • @user76856: I was thinking of typical functions that compile/execute regular expressions (normally there's a function for each step). With regexps, you use parentheses to create subexpressions, and regexp function let you get an array of them to inspect afterwards. For example, `([0-9]+)-([0-9]+)` parses values like "123-4567", with "123" and "4567" being subexpressions. So, when supplying a "flags" value to such a function something like `CASE_INSENSITIVE | SUBEXPR_CAPTURE` is more meaningful than just SUBEXPR_CAPTURE, even though the numeric value of the resultant enum is the same. – Tony Delroy May 25 '11 at 16:02
  • That's interesting, I believed it was forbidden... The example may be quite useful. – neodelphi May 25 '11 at 16:41
  • @neodelphi: well, the comment-length limits forced a simplification: if you haven't provided an `operator|` overload for the enum, it will decay to an `int` - if the function takes `int flags` (as in regcomp/regexec) that's fine, otherwise it may needs an explicit conversion back to the enum type. – Tony Delroy May 26 '11 at 01:41
  • @Tony: I've never been so comfortable with those conversions by the way. I mean, it's a neat packing trick and all, but getting a value that is not part of the enum sounds like a subversion of the type system. For example, it's not accounted for when the compiler checks a `switch` statement. I much prefer either have two distinct enums (and arguments) or a dedicated purpose "int packing" class with pre-defined constants. – Matthieu M. May 26 '11 at 06:25
  • @Matthieu: good points, though (as you'd know but for the sake of other readers) the "value that is not part of the enum" is of course a programmer-intuition thing rather than any limitation suggested by the Standard. It's mainly seen in old C APIs, and with bit fields ala `struct { int x :2; bool y :1; ...}` you can achieve the same kind of layouts anyway without the hackery, though it's painful to specify a bit layout that matches an existing enum-based layout across multiple systems. Your dedicated "int packing" class may well be easiest when the need's there.... – Tony Delroy May 26 '11 at 07:08
  • @Tony: indeed, for the compiler any value is good as long as it fits into the enum representation, this why even after a `switch` figuring a `case` clause with a `return` for every enum member, the compiler will still complains that some paths may not return, and you need to add an `assert`, `unreachable` hack or return a default value... – Matthieu M. May 26 '11 at 07:31