Topic: using declaration and enum inconsistent?
Author: Richard Smith <richard@ex-parrot.com>
Date: 02 Oct 02 03:16:03 GMT Raw View
Francis Glassborow wrote:
> In article <8c8b368d.0209260513.5ac9ca14@posting.google.com>, Randy
> Maddox <rmaddox@isicns.com> writes
>
>>So, in the one case a using declaration naming a class type introduces
the
>>name of the class, plus the names of its members, while a using
declaration
>>naming an enum type introduces only the name of the type, which seems
rather
>>less useful by comparison.
>
>
> The problem is that if the using declaration of an enum type
introduced
> all the named enumeration constants, it would result in conflicts
> between different enums that use the same enumeration constants. I am
> not saying that the selected solution was perfect, just that it was a
> judgement call.
A pattern that I find useful in this situation is:
namespace colours
{
enum enum_t { red, green, blue };
}
... then I can use an using directive to get the name of all the enum
values:
int main()
{
using namespace colours;
colours::enum_t col = red;
}
(In this example I could have just written ``enum_t col = red'', but I
find this less clear. And there might be multiple enum_ts in scope, in
which case it would be ambiguous.)
--
Richard Smith
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: 02 Oct 02 03:16:56 GMT Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote in message
news:<+VfqhtVKtEl9EwCM@robinton.demon.co.uk>...
> The problem is that if the using declaration of an enum type
introduced
> all the named enumeration constants, it would result in conflicts
> between different enums that use the same enumeration constants. I am
> not saying that the selected solution was perfect, just that it was a
> judgement call.
>
>
Well, I certainly can't argue with that, but it sure would have been a
lot nicer it the using declaration did introduce the named enumerated
constants, and the name conflict issue could have been gotten around
by qualifying the constant name with the enumeration name. For
example,
enum MyEnum {ValOne, ValTwo};
using MyEnum;
Foo(MyEnum::ValOne); // non-existent syntax to disambiguate
That is, I would be happy even if I had to qualify the constant name
with the enumeration name. At least that would have been clear what
enumeration the constant was from.
Of course, it's clearly too late now to do anything about this. So it
goes.
Thanks for taking the time to respond. I appreciate the insight into
the thinking that went into the decision.
Randy.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: rmaddox@isicns.com (Randy Maddox)
Date: 27 Sep 2002 07:24:04 -0400 Raw View
There appears to be a possible inconsistency in the way that a using
declaration works with an enumeration. To illustrate, the following snippet
contains a using std::string declaration, which introduces not only the name
string, but also the names of the members of class string, e.g.,
string.assign().
#include <iostream>
#include <string>
int main()
{
using std::string;
string s;
s.assign("String value");
std::cout << s << std::endl;
return 0;
}
OTOH, the following snippet contains a using class_name::enum_name
declaration, which introduces only the name of the enum and not the values
enumerated.
class MyClass
{
public:
enum MyEnum { ValOne, ValTwo };
};
int main()
{
using MyClass::MyEnum;
MyEnum enumVar; // OK
enumVar = ValOne; // ERROR!
enumVar = MyClass::ValOne; // OK
};
So, in the one case a using declaration naming a class type introduces the
name of the class, plus the names of its members, while a using declaration
naming an enum type introduces only the name of the type, which seems rather
less useful by comparison.
Yes, I realize that the standard explicitly states in in a note to
paragraph 2 of subclause 7.3.3 [namespace.udecl] that this is the mandated
behavior. My question is, could someone please explain the rationale for
this difference, which seems, IMHO, to be a bit inconsistent.
Thanks.
Randy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Heinz Ozwirk" <wansor42@gmx.de>
Date: 28 Sep 02 15:34:19 GMT Raw View
"Randy Maddox" <rmaddox@isicns.com> wrote in message news:8c8b368d.0209260513.5ac9ca14@posting.google.com...
> There appears to be a possible inconsistency in the way that a using
> declaration works with an enumeration. To illustrate, the following snippet
> contains a using std::string declaration, which introduces not only the name
> string, but also the names of the members of class string, e.g.,
> string.assign().
>
> #include <iostream>
> #include <string>
>
> int main()
> {
> using std::string;
>
> string s;
>
> s.assign("String value");
>
> std::cout << s << std::endl;
>
> return 0;
> }
std::string::assign is not introduced into your namespace. It only becomes visible in statement like s.assign(...) because s is of type std::string and operator.() requires as its right operand a member of the class type of its left operand. But that has nothing to do with namespaces at all.
> OTOH, the following snippet contains a using class_name::enum_name
> declaration, which introduces only the name of the enum and not the values
> enumerated.
>
> class MyClass
> {
> public:
>
> enum MyEnum { ValOne, ValTwo };
> };
>
> int main()
> {
> using MyClass::MyEnum;
>
> MyEnum enumVar; // OK
>
> enumVar = ValOne; // ERROR!
> enumVar = MyClass::ValOne; // OK
> };
Unlike classes, enums are no namespaces. The name of the enum type and the names of its values are members of the same namespace. "using" one member of a namespace does not introduce any other members of that namespace (or does "using std::string" imply "using std::cout"...)
Finally, have a look at the quallified names of string, assign, MyEnum and ValOne:
string std::string
assign std::string::assign
MyEnum MyClass::MyEnum
ValOne MyClass::ValOne
Regards
Heinz
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: acehreli@yahoo.com (Ali Cehreli)
Date: 28 Sep 02 15:34:34 GMT Raw View
rmaddox@isicns.com (Randy Maddox) wrote in message news:<8c8b368d.0209260513.5ac9ca14@posting.google.com>...
> There appears to be a possible inconsistency in the way that a using
> declaration works with an enumeration. To illustrate, the following snippet
> contains a using std::string declaration, which introduces not only the name
> string, but also the names of the members of class string, e.g.,
> string.assign().
I don't agree with you here. You cannot write only 'assign' in your
code. You still need to refer to it as '.assign' with a variable of
type 'string' on the left hand side when calling it; and as
string::assign when for example initalizing a member function pointer.
The same applies for types defined in string as well: We must refer to
'npos' member of 'string' as 'string::npos.'
> #include <iostream>
> #include <string>
>
> int main()
> {
> using std::string;
>
> string s;
>
> s.assign("String value");
Here, 'assign' alone would mean something else.
> std::cout << s << std::endl;
>
> return 0;
> }
>
> OTOH, the following snippet contains a using class_name::enum_name
> declaration, which introduces only the name of the enum and not the values
> enumerated.
>
> class MyClass
> {
> public:
>
> enum MyEnum { ValOne, ValTwo };
> };
>
> int main()
> {
> using MyClass::MyEnum;
>
> MyEnum enumVar; // OK
>
> enumVar = ValOne; // ERROR!
> enumVar = MyClass::ValOne; // OK
This is consistent with the string::npos example. Sorry, I don't see
any inconsistency here.
Ali
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Hyman Rosen <hyrosen@mail.com>
Date: 28 Sep 02 15:34:44 GMT Raw View
Randy Maddox wrote:
> There appears to be a possible inconsistency in the way that a using
> declaration works with an enumeration. To illustrate, the following snippet
> contains a using std::string declaration, which introduces not only the name
> string, but also the names of the members of class string, e.g.,
> string.assign().
No. Notice that all uses of members of string appear either as
string::name or some_string.name. No members are "introduced"
in the sense of being able to be used alone.
> OTOH, the following snippet contains a using class_name::enum_name
> declaration, which introduces only the name of the enum and not the values
> enumerated.
Just like string. And since enumerators are not members of the
enumeration type, you then can't get at them via enum_name::.
But naked enumerators are problematic anyway. Stick the enum
declaration in a namespace, and then using the namespace will
give you the effect you want.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Sungbom Kim <musiphil@bawi.org>
Date: 28 Sep 02 15:34:56 GMT Raw View
Randy Maddox wrote:
>
> There appears to be a possible inconsistency in the way that a using
> declaration works with an enumeration. To illustrate, the following snippet
> contains a using std::string declaration, which introduces not only the name
> string, but also the names of the members of class string, e.g.,
> string.assign().
I think you're mistaken here. The names of the members are not
introduced by the using declaration. In the example below, calling
s.assign() is possible even without the using declaration if s is
declared as a std::string, and calling assign() (without "s.") is
impossible even with the using declaration.
>
> #include <iostream>
> #include <string>
>
> int main()
> {
> using std::string;
>
> string s;
>
> s.assign("String value");
>
> std::cout << s << std::endl;
>
> return 0;
> }
>
> OTOH, the following snippet contains a using class_name::enum_name
> declaration, which introduces only the name of the enum and not the values
> enumerated.
>
> [ example snipped ]
>
> So, in the one case a using declaration naming a class type introduces the
> name of the class, plus the names of its members, while a using declaration
> naming an enum type introduces only the name of the type, which seems rather
> less useful by comparison.
>
> Yes, I realize that the standard explicitly states in in a note to
> paragraph 2 of subclause 7.3.3 [namespace.udecl] that this is the mandated
> behavior. My question is, could someone please explain the rationale for
> this difference, which seems, IMHO, to be a bit inconsistent.
Take this example:
namespace NS {
struct S { static int i; };
enum E { a, b };
}
using NS::S;
using NS::E;
By using NS::S, NS::S is introduced into the declarative region
but not NS::S::i.
By using NS::E, NS::E is introduced into the declarative region
but not NS::E::a or NS::E::b.
I see no inconsistency here. Do you?
--
Sungbom Kim <musiphil@bawi.org>
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 28 Sep 2002 15:59:10 -0400 Raw View
In article <8c8b368d.0209260513.5ac9ca14@posting.google.com>, Randy
Maddox <rmaddox@isicns.com> writes
>So, in the one case a using declaration naming a class type introduces the
>name of the class, plus the names of its members, while a using declaration
>naming an enum type introduces only the name of the type, which seems rather
>less useful by comparison.
The problem is that if the using declaration of an enum type introduced
all the named enumeration constants, it would result in conflicts
between different enums that use the same enumeration constants. I am
not saying that the selected solution was perfect, just that it was a
judgement call.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]