Topic: Using directives (Was What is the standard for STL classes in 'std' namespace?)


Author: "AllanW {formerly AllanW@my-dejanews.com}" <allan_w@my-dejanews.com>
Date: 1999/04/21
Raw View
In article <slrn7ho0f8.66n.sbnaran@localhost.localdomain>,
  sbnaran@uiuc.edu wrote:
> On 19 Apr 99 21:17:11 GMT, Francis Glassborow
>
> >AFAIR that is one of the major differences between using directives and
> >using declarations.  Directives tell the compiler where it can look if
> >it needs to (which it doesn't if there is already a declaration of the
> >identifier in scope), declarations pull in all the declarations of the
> >identifier to the current scope.
>
> So why is it that in a namespace scope shadowing occurs?
>    namespace M { using namespace N; void f(double); }
> In namespace M, M::f(double) shadows N::f(int).
>
> But in the global scope, there is no shadowing.  Why?
>    using namespace N; void f(double);
> Here, ::f(double) does not shadow N::f(int).

I'd venture a guess: Because you explicitly called M::f.

The corresponding example in global namespace would be:
    namespace N { void f(int); }
    using namespace N;
    void f(double);
    int main() { ::f(3); }

----
Allan_W@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/04/21
Raw View
sbnaran@localhost.localdomain (Siemel Naran) writes:

> But in the global scope, there is no shadowing.  Why?
>    using namespace N; void f(double);
> Here, ::f(double) does not shadow N::f(int).

Sure it does. Calling ::f(4) will call ::f(double), not N::f(int);

Martin


[ 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@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1999/04/21
Raw View
On 21 Apr 1999 20:43:40 GMT, Martin von Loewis
>sbnaran@localhost.localdomain (Siemel Naran) writes:

>> But in the global scope, there is no shadowing.  Why?
>>    using namespace N; void f(double);
>> Here, ::f(double) does not shadow N::f(int).
>
>Sure it does. Calling ::f(4) will call ::f(double), not N::f(int);

No, that's not what my little program did.  I used both como and
egcs.  Both wound up calling N::f(int).

--
----------------------------------
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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/04/21
Raw View
On 19 Apr 99 21:17:11 GMT, Francis Glassborow

>AFAIR that is one of the major differences between using directives and
>using declarations.  Directives tell the compiler where it can look if
>it needs to (which it doesn't if there is already a declaration of the
>identifier in scope), declarations pull in all the declarations of the
>identifier to the current scope.

So why is it that in a namespace scope shadowing occurs?
   namespace M { using namespace N; void f(double); }
In namespace M, M::f(double) shadows N::f(int).

But in the global scope, there is no shadowing.  Why?
   using namespace N; void f(double);
Here, ::f(double) does not shadow N::f(int).

--
----------------------------------
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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/04/19
Raw View
On 16 Apr 99 06:54:05 GMT, Matt Seitz <mseitz@meridian-data.com> wrote:
>Siemel Naran <sbnaran@fermi.ceg.uiuc.edu> wrote in message

>>    namespace N { void f(int); }
>>    using namespace N;
>>    void f(double);
>>    int main() { f(3); }
>>       // you'd expect this to call N::f(int)
>>       // but instead it calls it calls ::f(double)
>>       // after converting int to double, or 3 to 3.0
>>       // because the stuff in namespace N is shadowed
>
>According to THE C++ PROGRAMMING LANGUAGE 3rd Edition, section C.10, names
>introduced by a using-directive do not hide (or "shadow") names.  Based on
>that, I believe main() global f(double) and N::f(int) would be considered
>overloaded, and main would call N::f(int) as the closest match.

Your thinking seems to be right.  I tried the above program on
como and egcs and the output is
   N::f(int)

Now heres a variation program
    #include <iostream.h>
    namespace N { void f(int){cout<<"N::f(int)\n";} }
    namespace M { using namespace N; void f(double){cout<<"f(double)\n";} }
    int main() { M::f(3); }
Here the shadowing argument seems to apply as como and egcs output
   f(double)


So I find myself a little confused now.

--
----------------------------------
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/04/19
Raw View
In article <slrn7hk7bc.sjj.sbnaran@localhost.localdomain>, Siemel Naran
<sbnaran@localhost.localdomain> writes
>Your thinking seems to be right.  I tried the above program on
>como and egcs and the output is
>   N::f(int)
>
>Now heres a variation program
>    #include <iostream.h>
>    namespace N { void f(int){cout<<"N::f(int)\n";} }
>    namespace M { using namespace N; void f(double){cout<<"f(double)\n";} }
>    int main() { M::f(3); }
>Here the shadowing argument seems to apply as como and egcs output
>   f(double)

AFAIR that is one of the major differences between using directives and
using declarations.  Directives tell the compiler where it can look if
it needs to (which it doesn't if there is already a declaration of the
identifier in scope), declarations pull in all the declarations of the
identifier to the current scope.

>
>
>So I find myself a little confused now.

Francis Glassborow      Journal Editor, 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: brahms@mindspring.com (Stan Brown)
Date: 1999/04/18
Raw View
In this next-to-last year of the millennium, jcobban@nortelnetworks.com
(Jim Cobban) wrote in comp.std.c++:
>Namespaces are only an advantage IF YOU HAVE ENCOUNTERED A NAME CONFLICT.
>If you have not then they are a bloody waste of time and you are glad that
>the language designers provided an out.

By that argument, fire insurance is worth buying only if you have already
had a fire. If not then it's a bloody waste of money.

--
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA
                                    http://www.mindspring.com/~brahms/
My reply address is correct as is. The courtesy of providing a correct
reply address is more important to me than time spent deleting spam.
---
[ 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: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/04/15
Raw View
smeyers@aristeia.com (Scott Meyers) writes:

> Is this true?  I'd expect this reference to "vector" to be ambiguous.  My
> understanding is that the using directive tells the compiler to treat the
> name std::vector as if it had been declared at global scope, just like the
> local template named vector.  Hence ::vector is ambiguous.  No?

No. If it would work that way, you had no way of referring to the
global vector. An (apparently implicit) rule for name lookup in C++ is
that there should be always a way to get exactly the type or object
you want.

For this particular case, the semantics is explained in
[namespace.qual]/2.

Regards,
Martin
---
[ 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: miker3@ix.netcom.com (Michael Rubenstein)
Date: 1999/04/15
Raw View
On 15 Apr 99 10:26:48 GMT, Martin von Loewis
<loewis@informatik.hu-berlin.de> wrote:

>miker3@ix.netcom.com (Michael Rubenstein) writes:
>
>> Note, however, that Martin is incorrect about the first
>> declaration of ::vector<int>.  Again, there is no unqualified
>> lookup, ::vector<int> does not refer to std::vector.  Also from
>> 7.3.4:
>>=20
>>  A using=ADdirective does not add any members to the=20
>>  declarative region in which it appears.
>
>What you are missing is 3.4.3.2, [namespace.qual]/2:

No I am not.

>
>>> Given X::m (where X is a user=ADdeclared namespace), or given ::m
>>> (where X is the global namespace), let S be the set of all
>>> declarations of m in X and in the transitive closure of all
>>> namespaces nominated by using=ADdirectives in X and its used
>>> namespaces, except that using=ADdirectives are ignored in any
>>> namespace, including X, directly containing one or more
>>> declarations of m.
>
>So in our case, X is the global namespace, and m is 'vector'. When we
>first lookup X::m, the we have a global using directive of std, so
>std::vector is in S. This is also the entity denoted by ::vector.

No.  Since the global namespace contains a declaration of vector,
namespace directives are ignored.

>
>On the second lookup, the global namespace contains a definition of
>vector, so the global using-directive is now ignored, and we get the
>global definition of ::vector.

The global namespace contains a definition in the first case
also.  The passage you cite does not except searching namespaces
nominated by using directives was ignored only if the declarative
region contains a declaration of m; it did not say that it was
ignored only if the declaration preceded the use of ::m.

--
Michael M Rubenstein
---
[ 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: "Matt Seitz" <mseitz@meridian-data.com>
Date: 1999/04/16
Raw View
Siemel Naran <sbnaran@fermi.ceg.uiuc.edu> wrote in message
news:slrn7h7c4f.mp6.sbnaran@fermi.ceg.uiuc.edu...
> On 13 Apr 99 18:59:42 GMT, Matt Seitz <mseitz@meridian-data.com> wrote:
> And what about
> 3) Using directives may intefere with function overloading.  Eg,
>    namespace N { void f(int); }
>    using namespace N;
>    void f(double);
>    int main() { f(3); }
>       // you'd expect this to call N::f(int)
>       // but instead it calls it calls ::f(double)
>       // after converting int to double, or 3 to 3.0
>       // because the stuff in namespace N is shadowed

According to THE C++ PROGRAMMING LANGUAGE 3rd Edition, section C.10, names
introduced by a using-directive do not hide (or "shadow") names.  Based on
that, I believe main() global f(double) and N::f(int) would be considered
overloaded, and main would call N::f(int) as the closest match.
---
[ 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: "Matt Seitz" <mseitz@meridian-data.com>
Date: 1999/04/16
Raw View
Ed Brey <brey@afd.mke.etn.com> wrote in message
news:7f2kak$666@interserv.etn.com...
> Jim Cobban <jcobban@nortelnetworks.com> wrote in message
> news:7f0bee$21q$1@bcarh8ab.ca.nortel.com...
> > I I therefore must assume that whatever
> > he might say in his public persona as inventor of C++ and defender of
the
> > standard, in writing the book he obviously thought that the examples
were
> > easier to read without all the qualifications.
>

No need to assume.  Dr. Stroustrup gives an explanation in section 3.3 of
THE C++ PROGRAMMING LANGUAGE, 3rd edition:

"It is generally in poor taste to dump every name from a namespace into the
global namespace.  However, to keep short the program fragments used to
illustrate language and library features, I omit repetitive '#includes' and
'std::' qualifications.  In this book, I use the standard library almost
exclusively, so if a name from the standard library is used, it either is a
use of what the standard offers or part of an explanation of how the
standard facility might be defined."
---
[ 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: smeyers@aristeia.com (Scott Meyers)
Date: 1999/04/13
Raw View
On 10 Apr 99 05:08:17 GMT, Siemel Naran wrote:

> If you say
>    #include <vector>
> then you must say
>    std::vector<int> v;
> Try to use this method if possible as you get the full
> benefit of namespaces.

I've heard this argument from lots of people, but I've never heard a
compelling rationale for it.  (I've heard rationales, just not compelling
ones.)  Since lots of people in this newsgroup pounce anytime somebody
employs a using directive, I'd be interested in just why people think
they're so bad.

Note that a using directive is unlike a #include in one important way: it
can't, in and of itself, yield a name conflict.  With namespaces, potential
ambiguity is not an error.  So if namespace Library1 defines a class Wombat
and namespace Library2 defines a class Wombat, the following is just
fine...

  using namespace Library1;
  using namespace Library2;    // fine, no name conflicts

....UNLESS somebody refers to the name Wombat, in which case the use must be
disambiguated, typically by prepending the namespace name to the use.

So I ask again:  just WHY is the use of using directives such a software
engineering sin?

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
---
[ 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: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/04/13
Raw View
smeyers@aristeia.com (Scott Meyers) writes:

> So I ask again:  just WHY is the use of using directives such a software
> engineering sin?

I think there are two complaints

a) they are hard to get rid of once introduced
b) they are counter-intuitive in boundary cases

Complaint a) typically results in the recommendation that using
directives in block scope are just fine - once you leave the function,
everything is like it was. A using directive on the global scope
introduced to use part of the namespace, it might require you to
qualify global names, even when you didn't expect a clash.

On part b), I'll try to list some of the obscurities, although I'm not
sure how relevant they are

#include <iostream>
using namespace std;

namespace{
  int cout;
}

There is no way of accessing the anonymous cout now, other than
reopening the anonymous namespace.

#include <vector>
using namespace std;

void foo()
{
  ::vector<int> x; // ok, denotes std::vector
}

template<class T>
class vector{};

void bar()
{
  ::vector<int> y; // ok, denotes ::vector now
}

It is confusing that using directives are considered in qualified name
lookup.

namespace A{
  int foo(int);
}

int foo(short);
using namespace A;
int dummy(foo(42));  // ok, calls A::foo

namespace B{
  using namespace A;
  int foo(long);
  int dummy(foo(42));  //ok, but calls B::foo(long)
}

It is confusing that namespace appear in the nearest enclosing
namespace, where they may be shadowed by names that would normally
appear 'worse' for lookup or overload resolution. Another variant of
the same problem

namespace A{
  struct Foo{Foo();};
}

namespace B{
  struct Foo{Foo();};
  namespace C{
    using namespace A;
    Foo f;               // This is B::Foo now!!!
  }
}

I don't know whether these are 'compelling' examples.

Regards,
Martin
---
[ 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: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/04/13
Raw View
Scott Meyers schrieb in Nachricht ...
>On 10 Apr 99 05:08:17 GMT, Siemel Naran wrote:
>
>> If you say
>>    #include <vector>
>> then you must say
>>    std::vector<int> v;
>> Try to use this method if possible as you get the full
>> benefit of namespaces.
>
>I've heard this argument from lots of people, but I've never heard a
>compelling rationale for it.  (I've heard rationales, just not compellin=
g
>ones.)  Since lots of people in this newsgroup pounce anytime somebody
>employs a using directive, I'd be interested in just why people think
>they're so bad.

I don't condemn them generally. I even use them sometimes (no pun intende=
d).
I see many (potential) problems though. A using directive may introduce v=
ery
many names into a scope, especially if you regard recursive use of using
declarations during name lookup. It introduces those names blindly. Also
IMHO the scoping rules for using directives are rather complex and can
produce confusing results (see example below).

>Note that a using directive is unlike a #include in one important way: i=
t
>can't, in and of itself, yield a name conflict.  With namespaces, potent=
ial
>ambiguity is not an error.  So if namespace Library1 defines a class Wom=
bat
>and namespace Library2 defines a class Wombat, the following is just
>fine...
>
>  using namespace Library1;
>  using namespace Library2;    // fine, no name conflicts
>
>....UNLESS somebody refers to the name Wombat, in which case the use mus=
t
be
>disambiguated, typically by prepending the namespace name to the use.


But adding a using directives to existing code may produce many such
ambiguities (especially in a context where other using directives are
visible). You'd the have to disambiguate those manually - or explicitly
qualify anything you add.
If you add a using directive because a library vendor updated moved his c=
ode
into a namespace and those names clash with names in your own namespace
(used by directive), you will have a lot of work to do ...

Moreover, the main problem aren't ambiguities - they are detected by the
compiler. The real problem is the subtle way in which names may be hidden.
(In the example below the declaration of X::g might be indirectly
#included).

>So I ask again:  just WHY is the use of using directives such a software
>engineering sin?


Having many names (among them some I don't know or care about) added (in =
a
sense) to a scope that is not immediately obvious, adds to complexity.
Software engineering rules are (or should be) intended to reduce complexi=
ty.
Namespaces are intended to reduce complexity: If somebody else adds a nam=
e
to his namespace this shouldn't impact my code. Using directives (partly)
eliminate this protection. Having 'partly' in the last statement only mak=
es
it more complex - sometimes you produce compiler errors, sometimes you
don't. Using directives may also hide errors where the name you intended =
to
refer to isn't in scope.
To avoid excessive qualification of names, I vastly prefer using
declarations. They state exactly why I add them - which names I need. The=
y
really introduce a name into the scope where they appear - not into some
containing scope. One useful consequence of this is that they participate=
 in
overload resolution. If my use of a name really is ambiguous, they yield =
the
error messages I deserve.
So my basic rules are:
- If a qualified name is used in one context more than 2 or 3 times, try =
a
using declaration.
- If many names from one namespace are used in a local scope (like functi=
on
scope), so it will not be visible in other contexts, then a using directi=
ve
may be appropriate.

One small example:

#include<iostream>
using std::cout;    // I like using declarations
using std::endl;

namespace X {
 void g() { cout << "X::g called" << endl; }
};

namespace Y
{
 void g() { cout << "Y::g called" << endl; }

 namespace Z
 {
  using namespace X; // (1)
  //using X::g; // (2)
  void f()  { cout << "Y::Z::f calling g() - "; g(); }
 };
};

int main ()
{
 using namespace Y::Z; // (3)

cout << "main calling g() -    ";
 g();    // (4)

 f();

 return EXIT_SUCCESS;
}

I didn't check with the standard, but I think MSVC6 is right in producing
the following
Output:
    main calling g()  - X::g called
    Y::Z::f calling g() - Y::g called
This happens although the name g was available within main only by using
[line (3)] the namespace f is located in.

If you comment out (1) and activate line (2) instead, both contexts agree=
 on
the meaning of g():
    main calling g()  - X::g called
    Y::Z::f calling g() - X::g called


IMHO this behaviour is not intuitive.

[
BTW: If you leave in both (1) and (2) I get an ambiguity in line (4). I
think MSVC might be wrong on that one. (The definition of f still compile=
s
without error - and refers to X::g).
Of course without either (1) or (2), no 'g' is visible in line (4).
]
-- J=F6rg
---
[ 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: smeyers@aristeia.com (Scott Meyers)
Date: 1999/04/14
Raw View
On 13 Apr 99 12:43:37 GMT, Martin von Loewis wrote:
> #include <vector>
> using namespace std;
>
> void foo()
> {
>   ::vector<int> x; // ok, denotes std::vector
> }
>
> template<class T>
> class vector{};
>
> void bar()
> {
>   ::vector<int> y; // ok, denotes ::vector now
> }

Is this true?  I'd expect this reference to "vector" to be ambiguous.  My
understanding is that the using directive tells the compiler to treat the
name std::vector as if it had been declared at global scope, just like the
local template named vector.  Hence ::vector is ambiguous.  No?

> I don't know whether these are 'compelling' examples.

Well, they have convinced me that the chances for confusion are great.
Other postings in this thread have convinced me that using directives at
global scope are generally a bad idea.

One irony of this situation is that the logic I extolled in my original
posting runs counter to one of the things I wrote in Effective C++: "Guard
Against Potential Ambiguity."  Maybe it's time for me to review my own
book, sigh.

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD
---
[ 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/04/14
Raw View
Jim Cobban<jcobban@nortelnetworks.com> wrote:
>Stanley Friesen [Contractor] <stanley@west.sun.com> wrote:
>>They eliminate the advantage of using namespaces to begin with.
>
>However as discussions in this group and others have pointed out numerous
>times, about half of all programmers have NEVER encountered a name conflict,

And ninety percent of all statistics are made up on the spot.

>The only problem then is that the STL designers, KNOWING that namespaces
>are available to them, have been sloppy in choosing their names so that
>as soon as you include STL you are almost certain to hit a conflict.

This is like arguing that C programmers are sloppy for relying on
loops to branch back to the top, and failing to put labels there
as well.  Or that drivers are being foolish to drive in the rain,
just because they have windshield wipers.

>... if they had put all of their objects
>into some other namespace other than std, then there would be no problem
>with using namespace std.

This is a very, very funny thing to say.

If there were nothing in namespace std, you wouldn't be tempted to
mention it in a namespace directive.  Instead, the discussion would
be about "using namespace std_really" or something.

--
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              ]





Author: miker3@ix.netcom.com (Michael Rubenstein)
Date: 1999/04/14
Raw View
On 14 Apr 99 06:10:58 GMT, smeyers@aristeia.com (Scott Meyers)
wrote:

>On 13 Apr 99 12:43:37 GMT, Martin von Loewis wrote:
>> #include <vector>
>> using namespace std;
>>=20
>> void foo()
>> {
>>   ::vector<int> x; // ok, denotes std::vector
>> }
>>=20
>> template<class T>
>> class vector{};
>>=20
>> void bar()
>> {
>>   ::vector<int> y; // ok, denotes ::vector now
>> }
>
>Is this true?  I'd expect this reference to "vector" to be ambiguous.  M=
y
>understanding is that the using directive tells the compiler to treat th=
e
>name std::vector as if it had been declared at global scope, just like t=
he
>local template named vector.  Hence ::vector is ambiguous.  No?

That's not what the standard says *7.3.4)

 A using=ADdirective specifies that the names in the=20
 nominated namespace can be used in the scope in which the

 using=ADdirective appears after the using=ADdirective. During

 unqualified name lookup (3.4.1), the names appear as if=20
 they were declared in the nearest enclosing namespace=20
 which contains both the using=ADdirective and the=20
 nominated namespace.

In

 ::vector<int> y;

there is no unqualified name lookup, so using does not matter.

Note, however, that Martin is incorrect about the first
declaration of ::vector<int>.  Again, there is no unqualified
lookup, ::vector<int> does not refer to std::vector.  Also from
7.3.4:

 A using=ADdirective does not add any members to the=20
 declarative region in which it appears.

--
Michael M Rubenstein
---
[ 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/04/15
Raw View
On 14 Apr 99 06:10:58 GMT, Scott Meyers <smeyers@aristeia.com> wrote:

>Well, they have convinced me that the chances for confusion are great.
>Other postings in this thread have convinced me that using directives at
>global scope are generally a bad idea.

There's more.  Using-directives at global scope in the .header file
are a bad idea.  But using-directives at global scope in the .cpp
file are sometimes a good idea.  And using-directives at function
scope inside the .header or .cpp file are also sometimes a good idea.

--
----------------------------------
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: "J.Barfurth" <techview@bfk-net.de>
Date: 1999/04/15
Raw View
Scott Meyers schrieb in Nachricht ...
>On 13 Apr 99 12:43:37 GMT, Martin von Loewis wrote:
>> #include <vector>
>> using namespace std;
>>
>> void foo()
>> {
>>   ::vector<int> x; // ok, denotes std::vector
>> }
>>
>> template<class T>
>> class vector{};
>>
>> void bar()
>> {
>>   ::vector<int> y; // ok, denotes ::vector now
>> }
>
>Is this true?  I'd expect this reference to "vector" to be ambiguous.  M=
y
>understanding is that the using directive tells the compiler to treat th=
e
>name std::vector as if it had been declared at global scope, just like t=
he
>local template named vector.  Hence ::vector is ambiguous.  No?

I don't have the standard at hand right now, so I can't give any normativ=
e
references, but IIRC this basically works as follows:
A using directive (as opposed to a using _declaration_) does not declare =
any
names at any scope. Instead it is a _directive_ how to proceed in further
name lookup:
    If a name isn't available in the current scope, check the using
directives that are available in the current scope. For each of these, ch=
eck
if the name is available in that namespace. If it isn't, continue
recursively on using directives in that namespace. Treat each name found
this way, as if it was declared at [some common containing namespace] for
the purpose of this name lookup. Now, do scope and overload resolution on
the set of declarations assembled this way.

The main effect is this: as soon as the scope currently searched declares
the name, further using directives are not considered. This has been
described by other posters on this thread as 'shadowing'.

The effects of this can be seen in the sample in my other post: Within
namespace Y::Z the (visible here) declaration of Y::g prevents name looku=
p
from searching namespace X (so X::g leads to no ambiguity). From a scope
that is only using namespace Y::Z though, the outer declaration of Y::g i=
s
not available, so here X::g is found.

-- J=F6rg Barfurth
---
[ 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: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/04/15
Raw View
miker3@ix.netcom.com (Michael Rubenstein) writes:

> Note, however, that Martin is incorrect about the first
> declaration of ::vector<int>.  Again, there is no unqualified
> lookup, ::vector<int> does not refer to std::vector.  Also from
> 7.3.4:
>
> =09A using=ADdirective does not add any members to the
> =09declarative region in which it appears.

What you are missing is 3.4.3.2, [namespace.qual]/2:

>> Given X::m (where X is a user=ADdeclared namespace), or given ::m
>> (where X is the global namespace), let S be the set of all
>> declarations of m in X and in the transitive closure of all
>> namespaces nominated by using=ADdirectives in X and its used
>> namespaces, except that using=ADdirectives are ignored in any
>> namespace, including X, directly containing one or more
>> declarations of m.

So in our case, X is the global namespace, and m is 'vector'. When we
first lookup X::m, the we have a global using directive of std, so
std::vector is in S. This is also the entity denoted by ::vector.

On the second lookup, the global namespace contains a definition of
vector, so the global using-directive is now ignored, and we get the
global definition of ::vector.

Regards,
Martin
---
[ 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/04/15
Raw View
On 14 Apr 99 05:18:21 GMT, Jim Cobban <jcobban@nortelnetworks.com> wrote:

>However as discussions in this group and others have pointed out numerous
>times, about half of all programmers have NEVER encountered a name conflict,
>even when working on huge projects which include code from multiple sources.

One reason why there have not been conflicts is that programmers go out
of their way to find unique names.  For example, they use prefixes.
Example: Rogue Wave software has the following symbol "RWCRegexp".  But
"RW::Regexp" is better.

Another reason is that in the good old days, helper classes and
functions had internal linkage.  So two helper classes with the same
name couldn't conflict.  Eg,

   // file1.c
   #include "file1.h"
   class Helper { ... }
   ...

   // file2.c
   #include "file2.h"
   class Helper { ... }
   ...

Link file1.o and file2.o together, there are no multiple redefinition
errors of class ::Helper.  But today, compilers should give these
errors.  The solution is to put class Helper into an unnamed namespace.


--
----------------------------------
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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/04/15
Raw View
On 14 Apr 99 05:18:49 GMT, Jim Cobban <jcobban@nortelnetworks.com> wrote:

>I find it interesting that most of Dr.Stroustrup's examples will only
>compile IF you put a using namespace std; into them.  He himself does not
>qualify all of the names with std::.  I therefore must assume that whatever
>he might say in his public persona as inventor of C++ and defender of the
>standard, in writing the book he obviously thought that the examples were
>easier to read without all the qualifications.

I would prefer that the next version of Stroustrup's book use namespace
qualifications fully.

However, using-directives inside a .cpp file are sometimes ok.  The
short examples in Stroustrup's book can be thought of as snippets from
a .cpp file.

Also, for larger programs -- say, five hundred lines or more --
namespaces are likely to be a sure win.  For your twenty line program,
namespace suck.

--
----------------------------------
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: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/04/15
Raw View
Jim Cobban <jcobban@nortelnetworks.com> wrote in message
news:7f0bee$21q$1@bcarh8ab.ca.nortel.com...
> I find it interesting that most of Dr.Stroustrup's examples will only
> compile IF you put a using namespace std; into them.  He himself does not
> qualify all of the names with std::.  I therefore must assume that
whatever
> he might say in his public persona as inventor of C++ and defender of the
> standard, in writing the book he obviously thought that the examples were
> easier to read without all the qualifications.

Dr. Stroustrup's has the luxury in his texts of dealing with small code
fragments operating in a narrow scope.  For education purposes, when the
material under study is STL, using std:: would be basically redundant, since
names can't refer to much else.  However, for commercial applications, STL
is just one tool in use among many (present and future), and it is useful to
explicitly specify which tool a given name is referring to.
---
[ 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: stanley@west.sun.com (Stanley Friesen [Contractor])
Date: 1999/04/13
Raw View
In article <MPG.117c854bf8e6af8e98969e@news.teleport.com>,
Scott Meyers <smeyers@aristeia.com> wrote:
>I've heard this argument from lots of people, but I've never heard a
>compelling rationale for it.  (I've heard rationales, just not compelling
>ones.)  Since lots of people in this newsgroup pounce anytime somebody
>employs a using directive, I'd be interested in just why people think
>they're so bad.

They eliminate the advantage of using namespaces to begin with.
>
>Note that a using directive is unlike a #include in one important way: it
>can't, in and of itself, yield a name conflict.  With namespaces, potential
>ambiguity is not an error.  So if namespace Library1 defines a class Wombat
>and namespace Library2 defines a class Wombat, the following is just
>fine...
>
>  using namespace Library1;
>  using namespace Library2;    // fine, no name conflicts
>
>....UNLESS somebody refers to the name Wombat, in which case the use must be
>disambiguated, typically by prepending the namespace name to the use.

Imagine that the two namespaces are in different headers, provided
by different third-party library vendors - and you just recieved the latest
version of each library, AND that you have been using Library1::Wombat without
conflict until now.  Suddenly you have a major conflict between them
*if* you have used using directives.  Now you have to go over all your
code and rewrite parts of it to work with the new Library2.

If you did things right and only used qualified names and/or a few
using declarations, everything is still fine and dandy - you need make no
code changes at all.

If you use Library1::Wombat frequently, then doing
using Library1::Wombat;
is a good way to simplify things, without chance of later conflict.
---
[ 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: "Matt Seitz" <mseitz@meridian-data.com>
Date: 1999/04/13
Raw View
Scott Meyers <smeyers@aristeia.com> wrote in message
news:MPG.117c854bf8e6af8e98969e@news.teleport.com...
> I've heard this argument from lots of people, but I've never heard a
> compelling rationale for it.  (I've heard rationales, just not compelling
> ones.)  Since lots of people in this newsgroup pounce anytime somebody
> employs a using directive, I'd be interested in just why people think
> they're so bad.

Dr. Stroustrup makes a couple of arguments against using-directives in
section 17.4.1 of THE DESIGN AND EVOLUTION OF C++.
1)  A using-directive makes an unknown set of names available.  If the
namespace is changed, the set of names made available also changes.
2)  Programs that use explicit qualification and using-declarations are
"clearer" than programs that use using-directives.
---
[ 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@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1999/04/14
Raw View
On 13 Apr 99 18:59:42 GMT, Matt Seitz <mseitz@meridian-data.com> wrote:

>Dr. Stroustrup makes a couple of arguments against using-directives in
>section 17.4.1 of THE DESIGN AND EVOLUTION OF C++.

>1)  A using-directive makes an unknown set of names available.  If the
>namespace is changed, the set of names made available also changes.

Good.

>2)  Programs that use explicit qualification and using-declarations are
>"clearer" than programs that use using-directives.

Good.  The intent of the program is clearer to someone reading the
code.  For sure, the prefix "myspace::" is somewhat tedious to
write and read.  But in the long run, it seems to help.


And what about
3) Using directives may intefere with function overloading.  Eg,
   namespace N { void f(int); }
   using namespace N;
   void f(double);
   int main() { f(3); }
      // you'd expect this to call N::f(int)
      // but instead it calls it calls ::f(double)
      // after converting int to double, or 3 to 3.0
      // because the stuff in namespace N is shadowed

--
----------------------------------
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: "Jim Cobban" <jcobban@nortelnetworks.com>
Date: 1999/04/14
Raw View
In article <7evsnk$k3h@abyss.West.Sun.COM>,
Stanley Friesen [Contractor] <stanley@west.sun.com> wrote:
>In article <MPG.117c854bf8e6af8e98969e@news.teleport.com>,
>Scott Meyers <smeyers@aristeia.com> wrote:
>>I've heard this argument from lots of people, but I've never heard a
>>compelling rationale for it.  (I've heard rationales, just not compelling
>>ones.)  Since lots of people in this newsgroup pounce anytime somebody
>>employs a using directive, I'd be interested in just why people think
>>they're so bad.
>
>They eliminate the advantage of using namespaces to begin with.

However as discussions in this group and others have pointed out numerous
times, about half of all programmers have NEVER encountered a name conflict,
even when working on huge projects which include code from multiple sources.
Namespaces are only an advantage IF YOU HAVE ENCOUNTERED A NAME CONFLICT.
If you have not then they are a bloody waste of time and you are glad that
the language designers provided an out.

The only problem then is that the STL designers, KNOWING that namespaces are
available to them, have been sloppy in choosing their names so that as soon
as you include STL you are almost certain to hit a conflict.  In other words
using namespace std; is only a bad thing because of the sloppy programming
of the STL designers, who put everything into namespace std.  If they had
given their internal objects the sort of compound names which are necessary
in C programming to avoid conflicts, or if they had put all of their objects
into some other namespace other than std, then there would be no problem
with using namespace std.
--
Jim Cobban   |  jcobban@nortelnetworks.ca           |  Phone: (613) 763-8013
Nortel Networks Enterprise Solutions                |  FAX:   (613) 763-5199
---
[ 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: "Jim Cobban" <jcobban@nortelnetworks.com>
Date: 1999/04/14
Raw View
In article <37138ea9.0@newsread.exodus.net>,
Matt Seitz <mseitz@meridian-data.com> wrote:
>2)  Programs that use explicit qualification and using-declarations are
>"clearer" than programs that use using-directives.

I am glad you put quotation marks around "clearer".  Clearer is a value
judgement, not an absolute.  The proliferation of std::this and std::that
in my opinion makes the program ugly and harder to read.

I find it interesting that most of Dr.Stroustrup's examples will only
compile IF you put a using namespace std; into them.  He himself does not
qualify all of the names with std::.  I therefore must assume that whatever
he might say in his public persona as inventor of C++ and defender of the
standard, in writing the book he obviously thought that the examples were
easier to read without all the qualifications.

--
Jim Cobban   |  jcobban@nortelnetworks.ca           |  Phone: (613) 763-8013
Nortel Networks Enterprise Solutions                |  FAX:   (613) 763-5199
---
[ 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              ]