enum and C2825 
Author Message
 enum and C2825

Hello all.
Someone had posted this question before but he didn't get it answered and I
am wondering about the same thing. The problem relates to the C++ compiler
of VS.NET 2003.

This works (note the using declaration):

struct foo
{
    enum X { Y };

Quote:
};

using foo::X::Y;

foo::X func()
{
    return Y;

Quote:
}

This doesn't work (again, note using):

struct foo
{
    enum X { Y };

Quote:
};

using foo::X;

X func()
{
    return X::Y;

Quote:
}

It gives an error C2825 on the line with return X::Y. Can anyone please
explain why this is not legal?
Thanks a lot.
Ales.


Mon, 03 Oct 2005 04:12:55 GMT  
 enum and C2825

Quote:

> Hello all.
> Someone had posted this question before but he didn't get it answered
> and I am wondering about the same thing. The problem relates to the
> C++ compiler of VS.NET 2003.

> This works (note the using declaration):

> struct foo
> {
>     enum X { Y };
> };

> using foo::X::Y;

This should be an error - there is no item named foo::X::Y (see below).

Quote:

> foo::X func()
> {
>     return Y;
> }

> This doesn't work (again, note using):

> struct foo
> {
>     enum X { Y };
> };

> using foo::X;

> X func()
> {
>     return X::Y;

This isn't legal because the enumerators of an enum-type are not injected
into a nested namespace (the enum itself), but rather into the enclosing
namespace.

You could write

using foo;

X func()
{
    return X::Y;

Quote:
}
> }

> It gives an error C2825 on the line with return X::Y. Can anyone
> please explain why this is not legal?
> Thanks a lot.
> Ales.

-cd


Mon, 03 Oct 2005 06:01:12 GMT  
 enum and C2825



Quote:

> > Hello all.
> > Someone had posted this question before but he didn't get it answered
> > and I am wondering about the same thing. The problem relates to the
> > C++ compiler of VS.NET 2003.

> > This works (note the using declaration):

> > struct foo
> > {
> >     enum X { Y };
> > };

> > using foo::X::Y;

> This should be an error - there is no item named foo::X::Y (see below).

I agree that this should probably be an error, however, it is not, at least
not in VC++ 2003.

- Show quoted text -

Quote:

> > foo::X func()
> > {
> >     return Y;
> > }

> > This doesn't work (again, note using):

> > struct foo
> > {
> >     enum X { Y };
> > };

> > using foo::X;

> > X func()
> > {
> >     return X::Y;

> This isn't legal because the enumerators of an enum-type are not injected
> into a nested namespace (the enum itself), but rather into the enclosing
> namespace.

> You could write

> using foo;

> X func()
> {
>     return X::Y;
> }

> > }

> > It gives an error C2825 on the line with return X::Y. Can anyone
> > please explain why this is not legal?
> > Thanks a lot.
> > Ales.

> -cd

The line "using foo;" would give an error, because only qualified names are
allowed in using declaration - the scope that has the using declaration
already uses foo.

My thinking is this:
- The using declaration brings a name and all its nested names to that scope
containing the using declaration.
- enum declares a name (or doesn't it???).
- If the above are both true, I would expect the following to work - however
it doesn't in VC++ 2003 (it did in previous versions).
struct foo { enum X { Y }; };        // declaring nested names
using foo::X;                                // bringing foo::X and all
nested names into the current scope
X func() { return X::Y; }              // exploiting the fact that X is now
"virtually" in current scope

Any clues, like where in the C++ standard this behaviour is prescribed?



Mon, 03 Oct 2005 15:56:33 GMT  
 enum and C2825

Quote:




>>> using foo::X::Y;

>> This should be an error - there is no item named foo::X::Y (see
>> below).

> I agree that this should probably be an error, however, it is not, at
> least not in VC++ 2003.

Yeah, it's a known bug.

Quote:

> The line "using foo;" would give an error, because only qualified
> names are allowed in using declaration - the scope that has the using
> declaration already uses foo.

You're right!

Quote:

> My thinking is this:
> - The using declaration brings a name and all its nested names to
> that scope containing the using declaration.
> - enum declares a name (or doesn't it???).

enum declares a name, but no nested names - there is no name foo::X::Y in
your example.

Quote:
> - If the above are both true, I would expect the following to work -
> however it doesn't in VC++ 2003 (it did in previous versions).
> struct foo { enum X { Y }; };        // declaring nested names
> using foo::X;                                // bringing foo::X and
> all nested names into the current scope
> X func() { return X::Y; }              // exploiting the fact that X
> is now "virtually" in current scope

> Any clues, like where in the C++ standard this behaviour is
> prescribed?

7.2/10

The enum name and each enumerator declared by an enum-specifier is declared
in the scope that immediately contains the enum specifier.  These names obey
the scope rules defined for all names in (3.3) and (3.4). An enumerator
declared in class scope can be referred to using the class member access
operators (::, . (dot) and -> (arrow)), see 5.2.5.

7.3.3/2

The member name specified in a using declaration is declared in the
declarative region in which the using declaration appears. [Note: only the
specified name is so declared; specifying an enumeration name in a using
declaration does not declare its enumerators in the using declaration's
declarative region. ]

So, you ought to be able to write

using foo::Y;
using foo::X;

X func()
{
    return Y;

Quote:
}

... which does indeed compile with VC 7.1.

-cd



Mon, 03 Oct 2005 21:35:24 GMT  
 enum and C2825



Quote:




> >>> using foo::X::Y;

> >> This should be an error - there is no item named foo::X::Y (see
> >> below).

> > I agree that this should probably be an error, however, it is not, at
> > least not in VC++ 2003.

> Yeah, it's a known bug.

> > The line "using foo;" would give an error, because only qualified
> > names are allowed in using declaration - the scope that has the using
> > declaration already uses foo.

> You're right!

> > My thinking is this:
> > - The using declaration brings a name and all its nested names to
> > that scope containing the using declaration.
> > - enum declares a name (or doesn't it???).

> enum declares a name, but no nested names - there is no name foo::X::Y in
> your example.

> > - If the above are both true, I would expect the following to work -
> > however it doesn't in VC++ 2003 (it did in previous versions).
> > struct foo { enum X { Y }; };        // declaring nested names
> > using foo::X;                                // bringing foo::X and
> > all nested names into the current scope
> > X func() { return X::Y; }              // exploiting the fact that X
> > is now "virtually" in current scope

> > Any clues, like where in the C++ standard this behaviour is
> > prescribed?

> 7.2/10

> The enum name and each enumerator declared by an enum-specifier is
declared
> in the scope that immediately contains the enum specifier.  These names
obey
> the scope rules defined for all names in (3.3) and (3.4). An enumerator
> declared in class scope can be referred to using the class member access
> operators (::, . (dot) and -> (arrow)), see 5.2.5.

> 7.3.3/2

> The member name specified in a using declaration is declared in the
> declarative region in which the using declaration appears. [Note: only the
> specified name is so declared; specifying an enumeration name in a using
> declaration does not declare its enumerators in the using declaration's
> declarative region. ]

> So, you ought to be able to write

> using foo::Y;
> using foo::X;

> X func()
> {
>     return Y;
> }

> ... which does indeed compile with VC 7.1.

> -cd

Thanks a lot for the explanation - the standard excerpts and your example
cleared it out.
However, it might be interesting to think about if it wouldn't be better if
the enumerators were declared inside the enum-specifier, not on the same
level. Then if there were say 10 enumerators, one wouldn't have to type the
using declaration for each one of them but instead wrote a single using
declaration for the enum-specifier and refered to the enumerators by their
qualified name specifier::enumerator.


Mon, 03 Oct 2005 22:35:58 GMT  
 enum and C2825

Quote:

> Thanks a lot for the explanation - the standard excerpts and your
> example cleared it out.
> However, it might be interesting to think about if it wouldn't be
> better if the enumerators were declared inside the enum-specifier,
> not on the same level. Then if there were say 10 enumerators, one
> wouldn't have to type the using declaration for each one of them but
> instead wrote a single using declaration for the enum-specifier and
> refered to the enumerators by their qualified name
> specifier::enumerator.

It's interesting to note that that's how C# defines enums - the enumerators
are defined inside the enum-type's scope.  Unfortunately, C++ is stuck with
how they're defined in C - changing it would break far too much code.

You can come somewhat close in C++ by defining a class with public static
const int members instead of an enum, but it's not quite the same thing,
since the "enumerators" will then be of type int and not a distinct type.
You could go a step further and declare a class with a nested enum and
static const members of the enum type, but that's getting a bit excessive, I
think.  Even that doesn't quite work, since then the scope that contains the
enumerator names is not the enum type.

-cd



Mon, 03 Oct 2005 23:34:34 GMT  
 enum and C2825

Quote:
> It's interesting to note that that's how C# defines enums - the
enumerators
> are defined inside the enum-type's scope.  Unfortunately, C++ is stuck
with
> how they're defined in C - changing it would break far too much code.

> You can come somewhat close in C++ by defining a class with public static
> const int members instead of an enum, but it's not quite the same thing,
> since the "enumerators" will then be of type int and not a distinct type.
> You could go a step further and declare a class with a nested enum and
> static const members of the enum type, but that's getting a bit excessive,
I
> think.  Even that doesn't quite work, since then the scope that contains
the
> enumerator names is not the enum type.

> -cd

Exactly. Too bad C++ drags imperfections to be "backward" compatible with C
(maybe a compiler option could help here? ... just kidding).
Anyway, thanks again for your comments. :-)


Tue, 04 Oct 2005 17:16:20 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. typedef enum as subset of another enum

2. enum - enum ?

3. enum - enum ?

4. Enum on Hashtable help !

5. How to enum DirectoryEntries without foreach in C#??

6. enum and combo

7. Getting back int value from Enum?

8. ADSI:IIS properties, who to enum

9. getting at a managed enum in an unmanaged class

10. enum/c++/ms visual C++.net

11. using C# enum types in unmanged C++

12. ATL enum

 

 
Powered by phpBB® Forum Software