Stuart said:
I do like your comments about the other being a workaround, but
the other developers see adding the "::" to be unnecessary extra typing
and don't see that there's anything to work around.
This just looks like language support for a convention of using
"::" to separate a subsystem prefix name from the rest of the name.
Since for years people have been prepending their own prefix name in
fairly common ways, I just don't see how using "::" instead of "_" say
improves modularization.
It's not simply a text prefix convention, it instructs the compiler that
the names with that prefix are actually considered to be a unit by the
programmer. If not only for modularization, it also helps to denote in
the code and not just by convention (or comments, which are even more
flimsy) the actual intent of the programmer.
You have two steps to access declarations in a separate namespace. One
is to provide access to the declarations (via #include on the header)
and the other is to denote what you are using out of that header via
specific or namespace-wide using declarations. The using declarations
can be nicely scoped (e.g. inside a function), unlike simply including
an entire header file of declarations.
My short answer is "because using the language feature denotes
programmer intent better than agreed conventions".
So I think my problem lies in understanding your middle paragraph.
- what do you mean by "provide several different interfaces to a
namespace"?
Normally we have some classes we use publically, and the rest
is all neatly hidden in the subsystem by convention or by supplying
an interface class that hides the implementation. (but the
implementation
is still in the global namespace). How can you show some but not all
of the
namespace? And how is that any better than having a class that
does the public interface and has an internal implementation?
I did this on a recent project involving a user interface library and
several ways to access it.
Some users will simply use the library, and need access to the
foundation-type classes like the initialization of the UI.
Some users will need more, and perhaps want to design their own widgets.
For those that just want to /use/ the UI, I have an interface that
provides access to the main listener that handles mouse and keyboard
events, a way to register action callbacks, etc, in files such as
user_interface.h and action.h
These two have a few enum types and some pure virtual classes declared,
so compile time when you include them is minimal.
For those that want to extend the UI, they can instead include
widgets.h, and action_full.h, which includes definitions to classes they
would not normally need. These two in turn include parts of the user
interface they need to compile. Including them will be more taxing on
the compiler, but you need the extra access so you must pay for it.
- Everyone uses this phrase "pollution of the global namespace".
I can't find anything anywhere that explains why this matters.
Can you explain why it matters to me if I use a language feature
to resolve names of the form abc::def instead of just abc_def?
Sorry I'm so frustrated, but all I can find on the net is the mantra
with no explanation. Just because it has the word "pollution" in
it doesn't mean I'll blindly accept it on principle.
Yes I've heard the phrase a lot, but frankly I just don't understand
why I care whether the compiler has a flat list of names or
a hierarchical list of names. Especially if everyone recommends
you never do "using ThatNamespace;" so I have to use the full
name anyways.
The pollution that people talk about means the probability of name
clashes increasing. If two components both define a "string"
class/struct that they use internally and you try to put the two
together, there will be severe compilation issues. Instead of
convoluting either environment by calling them "our_string" and
"their_string", it is better modularization to declare each in the
namespace in which it is used. Many use std::string, but it does not fit
everyone's needs, so they are free to make their own, and it is
convenient to say "string" in your code with appropriate using
declarations instead of CString or AString or Our_string.
Sorry I'm long-winded. Short answer is: so you can write identifier
names that are simple and make sense, like string, Date, and Time and
still will not clash with others.
As for shortening access to things declared in the namespace, you don't
have to include the entire namespace.
Instead of "using namespace std;" you can have "using std::string; using
std:
stream;" if those are the only two you want shortcut access to.
You have to use the full "std::string str;" if you have another 'string'
type declared, so namespaces give you a way to remove naming clashes,
obviously you do this with prepending to the actual class names in the
global namespace.
- I suppose a similar question is why would I use
namespace { variables and routines }
instead of putting "static" in front of each of these?
Stuart
I am not sure about this one. I hope someone else in the group has a
better idea about the pros and cons of either way.
--Paul Bilnoski