Topic: extent using keyword to support class names
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/02/10 Raw View
In article <EUmUp2BeAHw2EwQI@robinton.demon.co.uk>,
francis@robinton.demon.co.uk says...
[ ... ]
> Well here we must disagree. Using directives should never be found in a
> header file.
I agree, but with one minor exception: it's fairly innocuous to have a
using directive inside an inline function, which will normally be
inside a header. This only introduces the names into the inline
function itself rather than code that includes the header...
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Omry Yadan" <omry_y@inter.net.il>
Date: 1999/02/07 Raw View
[... using class...]
>I use enums a lot, and its annoying to type full qualified names all
>the time. I tried "using Class::Enum" but neither of my two compilers
>(egcs and como) allow it, though. Is there a serious reason to
>disallow this?
I think it will be better to allow
using class ios;
to make all type definations and static functions availalbe in current
scope.
--
Omry Yadan.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/02/09 Raw View
Francis Glassborow wrote:
>
> In article <36B8097C.D2AF760E@physik.tu-muenchen.de>, Christopher
> Eltschka <celtschk@physik.tu-muenchen.de> writes
> >The problem is that this won't work with classes:
> >
> >class X
> >{
> >public:
> > enum E { e1, e2, e3 };
> >};
> >
> >void foo()
> >{
> > using X::e1; // Error: Cannot use 'using' from a class
> >};
> Apologies for not grasping what you were wanting. This opens up issues
> of style. Before we had namespaces encapsulating an enum in a class
> made good sense now I would advocate that they be moved out to the
> enclosing namespace and then the problem goes away.
>
> I would never consider writing a using declaration in a function, the
> appropriate place, IMO, for using declarations is in a namespace.
Could you explain this?
IMHO a using declaration is a declaration (it adds names to the
current scope), and therefore should use the same rule as any
other declaration: Avoid wide scopes. Of course, if some name
is used throughout the program, or throughout the members of a
namespace, this is the correct place to put the using decl. in.
But if there's a single function that uses them (or only this
function uses them so much that it makes sense to use a using
declaration), there's no reason to introduce that name into a
wider scope. The same is true if there are a few functions of
that type, but they are not related in any other way (as quite
probable for ios formatting flags).
>
> And to answer the point raised in a subsequent posting, just write your
> using declarations once in their own 'header' file and #include that
> where you want to use them.
And with this rule I disagree. IMHO Headers should not normally
have using declarations. There may be an exception if you want to
create a new namespace to merge things from other namespaces;
however this will probably be the exception rather than the rule.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/10 Raw View
In article <36C03585.463E8044@physik.tu-muenchen.de>, Christopher
Eltschka <celtschk@physik.tu-muenchen.de> writes
>> I would never consider writing a using declaration in a function, the
>> appropriate place, IMO, for using declarations is in a namespace.
>
>Could you explain this?
I must have been very tired when I wrote that because I normally
advocate exactly the reverse. names should be injected into the
smallest scope that covers their uses.
>IMHO a using declaration is a declaration (it adds names to the
>current scope), and therefore should use the same rule as any
>other declaration: Avoid wide scopes. Of course, if some name
>is used throughout the program, or throughout the members of a
>namespace, this is the correct place to put the using decl. in.
>But if there's a single function that uses them (or only this
>function uses them so much that it makes sense to use a using
>declaration), there's no reason to introduce that name into a
>wider scope. The same is true if there are a few functions of
>that type, but they are not related in any other way (as quite
>probable for ios formatting flags).
>
>>
>> And to answer the point raised in a subsequent posting, just write your
>> using declarations once in their own 'header' file and #include that
>> where you want to use them.
>
>And with this rule I disagree. IMHO Headers should not normally
>have using declarations. There may be an exception if you want to
>create a new namespace to merge things from other namespaces;
>however this will probably be the exception rather than the rule.
Well here we must disagree. Using directives should never be found in a
header file.
Using declarations should not normally occur as an incidental part of a
header file for something else. But a free standing header file that
covers the collection of using declarations that I always use in a
context are harmless and encourage programmers to avoid using
declarations. They also make code more readable by avoiding obscuring
the important detail behind routine bits (such as using declarations)
Francis Glassborow Chair of Association of C & C++ Users
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/02/03 Raw View
On 3 Feb 1999 17:57:37 GMT, Christopher Eltschka
>Francis Glassborow wrote:
>> Is it really so painful to write:
>>
>> using N::e1;
>> using N::e2;
>> using N::e3;
Yes. It leads to lots of code clutter. Imagine if we had to write
all these using-declarations in ten different functions, and the
enum defined 15 enumerations. That's 150 using-directives altogether.
Indeed, this is painful :).
Your previous post said that using enum directives opens up the
possibility of conflict because the using-directive may introduce
too many names into the local context. First, in practice this is
likely not to be a problem. But if it is a problem, then the
compiler will give an error message and we'll have to revert to
the full qualified way. But we were using the full qualified way
to begin with, so why complain :). Eg,
void f()
{
int e1;
using N::E;
cout << e1; // error N::e1 or e1
}
>IMHO, the rule of "using" should be relaxed here:
>using <class member> is only problematic, if the class member
>is really an object member - that is, if it is either a non-static
>method, or a non-static member variable. Static member functions,
>static member variables, types and enum constants are not associated
>with a particular object, so they should be accessible with using.
>Note that you can use them without an object, in the same way as
>if they were in a namespace. Just that you cannot use "using".
No, there's a healthy alternative. This alternative is healthy in
that it involves just as much typing as Francis' solution above. A
good compiler will optimize away the redundant variables. Because
remember that in in this "const double x=1.0; cout<<x;" the compiler
may optimize away 'x' and just write "cout<<1.0", and this is already
a common optimization. The using enum directive is a still healthier
alternative, I think.
using N::E; // in the current rules, e1 e2 e3 not introduced
const E e1=N::e1; // storage can be optimized away at compile time
const E e2=N::e2;
const E e3=N::e3;
cout << e1; // essentially "cout << N::e1"
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/04 Raw View
In article <36B8097C.D2AF760E@physik.tu-muenchen.de>, Christopher
Eltschka <celtschk@physik.tu-muenchen.de> writes
>The problem is that this won't work with classes:
>
>class X
>{
>public:
> enum E { e1, e2, e3 };
>};
>
>void foo()
>{
> using X::e1; // Error: Cannot use 'using' from a class
>};
Apologies for not grasping what you were wanting. This opens up issues
of style. Before we had namespaces encapsulating an enum in a class
made good sense now I would advocate that they be moved out to the
enclosing namespace and then the problem goes away.
I would never consider writing a using declaration in a function, the
appropriate place, IMO, for using declarations is in a namespace.
And to answer the point raised in a subsequent posting, just write your
using declarations once in their own 'header' file and #include that
where you want to use them.
Francis Glassborow Chair of Association of C & C++ Users
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1999/02/04 Raw View
On 01 Feb 99 23:56:26 GMT, Nathan Myers <ncm@nospam.cantrip.org> wrote:
>Siemel Naran<sbnaran@uiuc.edu> wrote:
>>For your example you could just do
>> cout << boolalpha; // or std::cout << std::boolalpha
>
>This assumes the extension.
What extension? The function
ios_base& boolalpha(ios_base&);
is indeed defined in the standard. Calling "cout<<boolalpha" ends
up calling "booalpha(cout)" and returns a reference to 'cout'.
What I don't understand is why std::boolalpha(ios_base&) needs to
return anything.
>>Anyway, why can't I use the more restrictive, but safer 'using'
>>declaration? Eg,
>> using std::ios::fmtflags; // or is it fmt_flags?
>> cout.setf(boolalpha);
>
>It's not necessary. Use:
First, this is beside the point. I can use using-enum-directives
in my own programs. This would allow me to get Priority::HIGH.
Priority::MEDIUM, and Priority::LOW into scope with minimal effort.
And this is just one example among hundreds.
> cout.setf(cout.boolalpha);
Stroustrup III sec 21.4.6 begins,
To save the programmer from having to deal with the state of
a stream in terms of flags, the standard library provides a
set of functions for manipulating that state.
The use of manipulators is good for two reasons. First, it
lets us write code like this:
cout << fixed << 3.0 << ' ' << scientific << 3.0 << '\n';
Second, the manipulator provides automation. It turns the
correct bits on and the correct bits off. An example of this
is std::fixed, which turns on the FIXED flag and turns off the
SCIENTIFIC flag. This sort of automation is more in the spirit
of C++.
> cout << cout.boolalpha;
>
>This code is easier to understand anyway.
I looked through the standard and couldn't find a function
ios_base& ios_base::operator<<(fmtflags);
or even
istream& istream::operator<<(fmtflags);
ostream& ostream::operator<<(fmtflags);
So then "cout << cout.boolalpha" calls ostream::operator<<(int),
which is surely not what I want.
Anyway, I think a better design would have been to make the
manipulators nested functions of class ios_base. Then we could
using-class-directives (eg, "using std::ios_base") to bring
these static functions into scope. But this design, nice as it
is, doesn't solve the world's problems.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Andrei Alexandrescu" <alexandrescua@micromodeling.com>
Date: 1999/02/02 Raw View
Francis Glassborow wrote in message ...
[snip]
I want to change gears a bit.
What about extendign 'using' as a Pascal-like 'with' statement? I mean,
class A
{
public:
int foo();
};
int main()
{
A a;
using (a)
{
foo();
}
}
I would like this especially in conjunction with iterators. I would write:
using (*iter)
statement
Andrei
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/02/03 Raw View
Francis Glassborow wrote:
>
> In article <slrn7ba5bk.kmr.sbnaran@dirac.ceg.uiuc.edu>, Siemel Naran
> <sbnaran@dirac.ceg.uiuc.edu> writes
> >No, enums are different from classes and unions. They introduce names
> >into the surrounding context. Eg,
> > namespace N { enum E { e1,e2,e3 }; }
> >introduces 'e1' 'e2' 'e3' into N, not N::E.
> Because an enum does not create a new scope.
>
> >
> >By contrast,
> > namespace N { struct I { int i1,i2,i3; }; }
> >introduces 'i1' 'i2' 'i3' into N::E.
>
> I think you meant N::I
>
> >
> >My proposed rule that "using N::E" introduces 'e1' 'e2' 'e3' into the
> >current scope makes sense from this point of view.
>
> Yes, I understood what you were proposing, but basically you are saying
> that the identifiers provided by an enum definition should be treated in
> a different way from all other identifiers. I do not buy it.
>
> >
> >Also observe that a 'using' declaration is kind of like defining a
> >class in the current scope (ie, if we weren't lazy to type, we wouldn't
> >need this keyword).
>
> No, a using declaration is exactly a declaration and NOT a definition.
> The two things should not be confused.
>
> Is it really so painful to write:
>
> using N::e1;
> using N::e2;
> using N::e3;
The problem is that this won't work with classes:
class X
{
public:
enum E { e1, e2, e3 };
};
void foo()
{
using X::e1; // Error: Cannot use 'using' from a class
};
IMHO, the rule of "using" should be relaxed here:
using <class member> is only problematic, if the class member
is really an object member - that is, if it is either a non-static
method, or a non-static member variable. Static member functions,
static member variables, types and enum constants are not associated
with a particular object, so they should be accessible with using.
Note that you can use them without an object, in the same way as
if they were in a namespace. Just that you cannot use "using".
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Omry Yadan" <omry_y@inter.net.il>
Date: 1999/01/30 Raw View
why not extent the using keyword to support class names?
this will make things like :
using namespace ios; // or using classspace ios, or whatever
cout.setf(boolalpha);
// instead of
//cout.setf(ios::boolalpha);
--
Omry Yadan
Israel.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/01/31 Raw View
On 30 Jan 99 23:10:01 GMT, Omry Yadan <omry_y@inter.net.il> wrote:
>why not extent the using keyword to support class names?
>this will make things like :
>
>using namespace ios; // or using classspace ios, or whatever
>cout.setf(boolalpha);
> // instead of
> //cout.setf(ios::boolalpha);
For your example you could just do
cout << boolalpha; // or std::cout << std::boolalpha
The use of manipulators rather than setf/unsetf is better because the
manipulator turns the correct bits off. Eg, std::fixed turns off the
SCIENTIFIC flag, and turns on the FIXED flag.
The "using namespace std::ios" makes sense to me. But what things in
class std::ios should be made available? The enums, of course. But
nested classes should also have to be made available, along with
static functions. Member functions should be made available, but
this doesn't make sense as member functions are always called with an
object.
Anyway, why can't I use the more restrictive, but safer 'using'
declaration? Eg,
using std::ios::fmtflags; // or is it fmt_flags?
cout.setf(boolalpha);
I use enums a lot, and its annoying to type full qualified names all
the time. I tried "using Class::Enum" but neither of my two compilers
(egcs and como) allow it, though. Is there a serious reason to
disallow this?
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/01 Raw View
In article <slrn7b7ph8.8ta.sbnaran@localhost.localdomain>, Siemel Naran
<sbnaran@localhost.localdomain> writes
>Anyway, why can't I use the more restrictive, but safer 'using'
>declaration? Eg,
> using std::ios::fmtflags; // or is it fmt_flags?
> cout.setf(boolalpha);
>I use enums a lot, and its annoying to type full qualified names all
>the time. I tried "using Class::Enum" but neither of my two compilers
>(egcs and como) allow it, though. Is there a serious reason to
>disallow this?
I think you already covered the ground when consider a class. We have
enough special cases already without adding to them. using declarations
introduce a single name into the current scope. That is all they ever
do. enums are no different from classes, structs or unions in this
respect.
Francis Glassborow Chair of Association of C & C++ Users
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@dirac.ceg.uiuc.edu (Siemel Naran)
Date: 1999/02/01 Raw View
On 01 Feb 99 01:48:13 GMT, Francis Glassborow
>In article <slrn7b7ph8.8ta.sbnaran@localhost.localdomain>, Siemel Naran
>>Anyway, why can't I use the more restrictive, but safer 'using'
>>declaration? Eg,
>> using std::ios::fmtflags; // or is it fmt_flags?
>> cout.setf(boolalpha);
>>I use enums a lot, and its annoying to type full qualified names all
>>the time. I tried "using Class::Enum" but neither of my two compilers
>>(egcs and como) allow it, though. Is there a serious reason to
>>disallow this?
>I think you already covered the ground when consider a class. We have
>enough special cases already without adding to them. using declarations
>introduce a single name into the current scope. That is all they ever
>do. enums are no different from classes, structs or unions in this
>respect.
No, enums are different from classes and unions. They introduce names
into the surrounding context. Eg,
namespace N { enum E { e1,e2,e3 }; }
introduces 'e1' 'e2' 'e3' into N, not N::E.
By contrast,
namespace N { struct I { int i1,i2,i3; }; }
introduces 'i1' 'i2' 'i3' into N::E.
My proposed rule that "using N::E" introduces 'e1' 'e2' 'e3' into the
current scope makes sense from this point of view.
Also observe that a 'using' declaration is kind of like defining a
class in the current scope (ie, if we weren't lazy to type, we wouldn't
need this keyword). Therefore,
namespace XYZ { using N::I; using N::E }
is practically the same as
namespace XYZ { struct I { int i1,i2,i3; }; enum E { e1,e2,e3 }; }
The 'using' declarations introduces N::I into XYZ, and it introduces
N::E and N::E::e[123] into XYZ.
Hopefully I've convinced you that the rule makes sense. The real
reason to allow the rule is that it is so useful. Enums are very
common, and most often, they are members of a class. For example,
I've written this simple class before,
class Priority
{
public:
enum priority { LOW, MEDIUM, HIGH };
Priority(priority);
friend bool operator==(Priority,Priority);
friend bool operator< (Priority,Priority);
};
Enums are safe alternatives to raw integers. In particular, the
enum ensures that every Priority instance we create will be LOW
MED or HIGH. So why not encourage their use by extending 'using'
directives to them?
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/02/01 Raw View
In article <slrn7ba5bk.kmr.sbnaran@dirac.ceg.uiuc.edu>, Siemel Naran
<sbnaran@dirac.ceg.uiuc.edu> writes
>No, enums are different from classes and unions. They introduce names
>into the surrounding context. Eg,
> namespace N { enum E { e1,e2,e3 }; }
>introduces 'e1' 'e2' 'e3' into N, not N::E.
Because an enum does not create a new scope.
>
>By contrast,
> namespace N { struct I { int i1,i2,i3; }; }
>introduces 'i1' 'i2' 'i3' into N::E.
I think you meant N::I
>
>My proposed rule that "using N::E" introduces 'e1' 'e2' 'e3' into the
>current scope makes sense from this point of view.
Yes, I understood what you were proposing, but basically you are saying
that the identifiers provided by an enum definition should be treated in
a different way from all other identifiers. I do not buy it.
>
>Also observe that a 'using' declaration is kind of like defining a
>class in the current scope (ie, if we weren't lazy to type, we wouldn't
>need this keyword).
No, a using declaration is exactly a declaration and NOT a definition.
The two things should not be confused.
Is it really so painful to write:
using N::e1;
using N::e2;
using N::e3;
??
This way you will not find code broken when someone adds another item to
the enum.
I need to be able to write:
using N::E;
without giving the maintainer of E the chance to break all my code.
> Therefore,
> namespace XYZ { using N::I; using N::E }
>is practically the same as
> namespace XYZ { struct I { int i1,i2,i3; }; enum E { e1,e2,e3 }; }
>The 'using' declarations introduces N::I into XYZ, and it introduces
>N::E and N::E::e[123] into XYZ.
And it is that last thing I object to.
Francis Glassborow Chair of Association of C & C++ Users
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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/02/01 Raw View
Siemel Naran<sbnaran@uiuc.edu> wrote:
> Omry Yadan <omry_y@inter.net.il> wrote:
>
>>why not extend the using keyword to support class names?
>>this will make things like :
>>
>>using namespace ios; // or using classspace ios, or whatever
>>cout.setf(boolalpha);
>> // instead of
>> //cout.setf(ios::boolalpha);
>
>For your example you could just do
> cout << boolalpha; // or std::cout << std::boolalpha
This assumes the extension.
>Anyway, why can't I use the more restrictive, but safer 'using'
>declaration? Eg,
> using std::ios::fmtflags; // or is it fmt_flags?
> cout.setf(boolalpha);
It's not necessary. Use:
cout.setf(cout.boolalpha);
or
cout << cout.boolalpha;
This code is easier to understand anyway.
By the way, it's clearer when discussing these constructs to use
the terms: using-declaration, using-directive (with hyphen).
Then you don't need quote-marks or other apparatus.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]