Changing namespaces

B

Blue Ocean

Forgive me for asking so many questions so quickly. I am simply
asking as they come up unanswered in my book.

Can you change namespaces half way through a file? For instance, if
you want to use std and then half way through switch to your own:
{
...
using namespace std;
cout << "doing polygons";
using namespace polygon;
cout << poly1;
...
}

I know that this is a ridiculous example. Why would anyone define an
outstream for a 3D object with the name cout. But, suppose they did,
would this code snippet work, or do you have to use just one namespace
per file and be explicit about the use of other namespaces?
 
J

John Harrison

Forgive me for asking so many questions so quickly. I am simply
asking as they come up unanswered in my book.

Can you change namespaces half way through a file? For instance, if
you want to use std and then half way through switch to your own:
{
...
using namespace std;
cout << "doing polygons";
using namespace polygon;
cout << poly1;
...
}

I know that this is a ridiculous example. Why would anyone define an
outstream for a 3D object with the name cout. But, suppose they did,
would this code snippet work, or do you have to use just one namespace
per file and be explicit about the use of other namespaces?

You aren't changing namespaces, you are adding to the set of namespaces
that will be searched. You can have as many 'using namespace ...' as you
like and all of them will be searched.

In your example, if cout was defined in namespace std and polygon, then
you would get a compiler error 'ambiguous name cout' or some such.

john
 
R

Russell Hanneken

Blue said:
Forgive me for asking so many questions so quickly. I am simply
asking as they come up unanswered in my book.

Can you change namespaces half way through a file? For instance, if
you want to use std and then half way through switch to your own:
{
...
using namespace std;
cout << "doing polygons";
using namespace polygon;
cout << poly1;
...
}

I think you misunderstand using directives. A using directive makes
names from a namespace available as if they had been declared in the
global namespace. The second using directive in your example doesn't
nullify the effect of the first one. Assuming there is a polygon::cout,
the code would fail to compile, because there would be a name conflict.

Since you're a Java programmer, this example might help:

import java.awt.*; // The java equivalent of a using directive.
import java.util.*;

public class Foo
{
public static void main (String[] args)
{
List list;
}
}

This Java code suffers from pretty much the same problem as your C++
example. Try to compile it and you'll see what I mean.
 
J

JustSomeGuy

John said:
You aren't changing namespaces, you are adding to the set of namespaces
that will be searched. You can have as many 'using namespace ...' as you
like and all of them will be searched.

In your example, if cout was defined in namespace std and polygon, then
you would get a compiler error 'ambiguous name cout' or some such.

john

Wow.. So if you put:

using namespace std;
using namespace system;
using namespace mine;

at the top of your code then all three namespaces will be searched... and
assuming there is no conflict they will be resolved?

So if you have "std:ios:in" in your code, you could change it for
using namespace std:
using namespace ios:
and then just specify "in"?
 
J

JKop

JustSomeGuy posted:
using namespace std;
using namespace system;
using namespace mine;

This will dump everything into the global namespace.

Not only can you just write:


string pp;


You can write:

::string pp;


Ahh!!


-JKop
 
A

Andre Kostur

JKop said:
JustSomeGuy posted:


This will dump everything into the global namespace.

Not only can you just write:


string pp;


You can write:

::string pp;

Somebody correct me if I'm wrong, but this is bad info.

I think of the using namespace declarations as adding to a search path for
identifiers, not actually copying them into other namespaces.

The "::string pp" is explicitly looking for a "string" identifier in the
global namespace, and no other namespaces. Thus the "::string" would not
be the same as "std::string".
 
R

Russell Hanneken

JustSomeGuy said:
Wow.. So if you put:

using namespace std;
using namespace system;
using namespace mine;

at the top of your code then all three namespaces will be searched... and
assuming there is no conflict they will be resolved?
Sure.

So if you have "std:ios:in" in your code, you could change it for
using namespace std:
using namespace ios:
and then just specify "in"?

I think you meant to type semicolons rather than colons at the end of
your using directives. Anyway, that wouldn't work, because ios is a
class, not a namespace.
 
J

John Harrison

Wow.. So if you put:

using namespace std;
using namespace system;
using namespace mine;

at the top of your code then all three namespaces will be searched... and
assuming there is no conflict they will be resolved?
Right


So if you have "std:ios:in" in your code, you could change it for
using namespace std:
using namespace ios:
and then just specify "in"?

No because ios is not a namespace, its a typedef for a template. But yes,
in general you're right.

namespace outer
{
namespace inner
{
int xxx;
}
}

using namespace outer;
using namespace inner;

int main()
{
xxx = 1;
}

john
 
J

John Harrison

JustSomeGuy posted:


This will dump everything into the global namespace.

Not only can you just write:


string pp;


You can write:

::string pp;


Ahh!!

Interesting, but ugly. I suppose that demonstrates that it's not really
the case that namespaces are searched, but rather that the names from a
namespace are put into the global namespace.

john
 
R

Russell Hanneken

Andre said:
Somebody correct me if I'm wrong, but this is bad info.

I think you're right. ::string fails to compile on GCC 3.3.3 and the
Comeau Online Compiler.
 
D

David Harmon

On 7 Jul 2004 13:34:39 -0700 in comp.lang.c++, (e-mail address removed)
(Blue Ocean) wrote,
 
B

Blue Ocean

Russell Hanneken said:
Blue Ocean wrote:
[snip]

Since you're a Java programmer, this example might help:

import java.awt.*; // The java equivalent of a using directive.
import java.util.*;

public class Foo
{
public static void main (String[] args)
{
List list;
}
}

This Java code suffers from pretty much the same problem as your C++
example. Try to compile it and you'll see what I mean.

This was an extremely helpful example, and now my eyes are open.
Thank you very much for the help.

PS This is the same person that was posting under blue ocean; now that
I have a gmail account, google will only let me post under my gmail
address.
 
J

John Harrison

Somebody correct me if I'm wrong, but this is bad info.

I think of the using namespace declarations as adding to a search path
for
identifiers, not actually copying them into other namespaces.

The "::string pp" is explicitly looking for a "string" identifier in the
global namespace, and no other namespaces. Thus the "::string" would not
be the same as "std::string".

I was surprised by JKop's example but I tried it on Comeau C++ and it
compiles. So unless Comeau is wrong the 'search path' model is wrong.
Should look at the standard I suppose.

john
 
J

John Harrison

I think you're right. ::string fails to compile on GCC 3.3.3 and the
Comeau Online Compiler.

The following compiles for me on Comeau C++, MSVC++ 7.1 and gcc 3.3.1

#include <string>
using namespace std;

int main()
{
::string x = "";
}

What code did you try?

john
 
R

Russell Hanneken

John said:
The following compiles for me on Comeau C++, MSVC++ 7.1 and gcc 3.3.1

#include <string>
using namespace std;

int main()
{
::string x = "";
}

What code did you try?

Interesting. Testing with both GCC and the Comeau Online compiler, your
code works, and so does this:

#include <string>
using namespace std;
::string x = "";

However, this does not work:

#include <string>

int main()
{
using namespace std;
::string x = "";
}

I guess this is somehow related to the scope of the using directive?
 
J

John Harrison

Interesting. Testing with both GCC and the Comeau Online compiler, your
code works, and so does this:

#include <string>
using namespace std;
::string x = "";

However, this does not work:

#include <string>

int main()
{
using namespace std;
::string x = "";
}

I guess this is somehow related to the scope of the using directive?

I think I'm really going to have to look this up in the standard, which is
always a scary prospect. But here's a guess, your version of the code
injects all the std namespace names into the scope of main, but ::string
ignores any names within the scope of main and just looks directly at the
global scope. I could be utterly wrong.

I don't like what I'm learning here though. I prefer the search path
model, but maybe there is some subtle reason why it wouldn't work.

john
 
I

Ioannis Vranos

Blue said:
Forgive me for asking so many questions so quickly. I am simply
asking as they come up unanswered in my book.

Can you change namespaces half way through a file? For instance, if
you want to use std and then half way through switch to your own:
{
...
using namespace std;
cout << "doing polygons";
using namespace polygon;
cout << poly1;
...
}

I know that this is a ridiculous example. Why would anyone define an
outstream for a 3D object with the name cout. But, suppose they did,
would this code snippet work, or do you have to use just one namespace
per file and be explicit about the use of other namespaces?


You should try to use using std:: statements in case you use 2-3 std
facilities, and use using namespace statements for more. And both these,
*in an as small scope as possible*.

Do not use using statements in global scope.



For example:


#include <iostream>


int main()
{
using std::cout;
using std::cin;

int x;

cin>>x;

// ...

cout<<x<<"\n And then...\n";

// ...

cout<<"End of operations!\n";
}




Another example:

#include <iostream>
#include <vector>


int main()
{
using namespace std;

vector<int>array(10);

for(vector<int>::size_type i=0; i<array.size(); ++i)
cin>>array;

// ...

}



Never use using statements in global scope. Doing this, is an attempt to
defeat the namespace system.


In this way you can define your own versions of facilities in your own
namespaces and use them interchangeably.






Regards,

Ioannis Vranos
 
I

Ioannis Vranos

John said:
I think I'm really going to have to look this up in the standard, which
is always a scary prospect. But here's a guess, your version of the
code injects all the std namespace names into the scope of main, but
::string ignores any names within the scope of main and just looks
directly at the global scope. I could be utterly wrong.

I don't like what I'm learning here though. I prefer the search path
model, but maybe there is some subtle reason why it wouldn't work.




From TC++PL 3:


"Operator summary:


scope resolution class_name :: member
scope resolution namespace_name :: member
global :: name
global :: qualified-name
"






Regards,

Ioannis Vranos
 
S

Sharad Kala

John Harrison said:
[snip]

I think I'm really going to have to look this up in the standard, which is
always a scary prospect. But here's a guess, your version of the code
injects all the std namespace names into the scope of main, but ::string
ignores any names within the scope of main and just looks directly at the
global scope. I could be utterly wrong.

I think you are right.
Section 3.4.3/4
A name prefixed by the unary scope operator :: (5.1) is looked up in global
scope, in the translation unit where it is used. The name shall be declared
in global namespace scope or shall be a name whose declaration is visible in
global scope because of a using-directive (3.4.3.2). The use of :: allows a
global name to be referred to even if its identifier has been hidden
(3.3.7).

-Sharad
 
A

Andre Kostur

John Harrison said:
John Harrison wrote:
On Wed, 07 Jul 2004 22:20:42 GMT, Russell Hanneken
<[email protected]>
[snip]

I think I'm really going to have to look this up in the standard,
which is always a scary prospect. But here's a guess, your version of
the code injects all the std namespace names into the scope of main,
but ::string ignores any names within the scope of main and just
looks directly at the global scope. I could be utterly wrong.

I think you are right.
Section 3.4.3/4
A name prefixed by the unary scope operator :: (5.1) is looked up in
global scope, in the translation unit where it is used. The name shall
be declared in global namespace scope or shall be a name whose
declaration is visible in global scope because of a using-directive
(3.4.3.2). The use of :: allows a global name to be referred to even
if its identifier has been hidden (3.3.7).

I stand corrected. Personally it seems kinda weird, but thems the
breaks. I wonder why the decision was made that using the "::" scope
operation still goes through the "search path"... I would have figured
that by saying "::" you _meant_ global only...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top