Speaking of headers, did you ever think about what you are really doing when you put using namespace my_util
in a header file? Sure, it might be annoying to namespace-qualify all the types in your declarations. But using namespace my_util
forces all the names in my_util
into the global namespace of everyone who includes your header file.
As usual, here is a small example:
my_iface.hxx
:
bool check(my_types::Foo foo, my_types::Bar bar); bool listen(my_types::Foo foo, my_types::Bar bar); bool digest(my_types::Foo foo, my_types::Bar bar);
The repeated namespace qualifying gets annoying, so you would rather do:
my_iface.hxx
:
using namespace my_types; bool check(Foo foo, Bar bar); bool listen(Foo foo, Bar bar); bool digest(Foo foo, Bar bar);
This is however a bad idea. “using namespace my_types
” (a using directive) exports all the types in my_types
into the global namespace, which I think everyone agrees is a bad idea. You could argue that a using declaration is better, as “using my_types::Foo
” only places Foo
into the global namespace. I would however disagree, as a smaller sin is still a sin.
And you’re not getting away that easily, this argument is also valid for std
! Yes, you need to type my_func(std::vector v)
in header files.
A final trick you might try is to only use using namespace
inside of your other namespaces, like so:
my_iface.hxx
:
namespace my_iface { using namespace my_types; bool check(Foo foo, Bar bar); bool listen(Foo foo, Bar bar); bool digest(Foo foo, Bar bar); }
This is still a bad idea. You are not polluting the global namespace any more, but you are polluting your own. There are at least two problems with this approach: First, someone who uses your libraries might now accidentally qualify Foo
as my_iface::Foo
. If you ever decide to clean up my_iface
and remove the using directive, that poor guys code is going to break. Also, if this guy decides he wants to have using namespace my_iface
somewhere in his code, he probably doesn’t want all your other namespaces (and std, boost or whatever) included as well.
As usual, normal politeness applies: A one-time annoyance for you is better than a repeated annoyance for all your users.
Hm, it all depends on why one is doing something. Extending a namespace A with another one B, by “using namespace B” in A, is (usually) a valid technique. Bringing in B just because it has some stuff one needs for implementation of A, is (usually) bad.
This is like deriving from classes.
Deriving to create a proper subclass is (usually) good, deriving just to gain access to some functionality is (usually) bad.
Cheers,
– Alf
Sure, if your intention is to put namespace B in namespace A, it is completely fine. But if your intention is to save some typing, a warning bell should go off.
Hi Anders,
I have been reading several of your articles and find them very informative. Your writing is easy to follow and you provide good code examples. However, several of these articles on header files only bash on existing practices, you don’t really offer any solutions. I was hoping you could give me some advice on the following issues:
1. I love the way that using statements clean up code, but I don’t want to add lots of needless symbols to the my namespace. Where do YOU recommend putting using statements?
2. I have a class that depends on an external library. Its constructor takes an object from that library as a parameter, so I need to have access to that library in both the .h and the .cpp files. I also have a pre-compiled header file (stdafx.h) that was automatically generated by Visual Studio. Where should I put the library’s #include statement? In the .h, in both the .h and the .cpp, in stdfax.h, or in all three?
Hi Dan, and thanks for your comment! I partially agree with your comment about bashing without providing solutions.
1: Here I think the case is fairly obvious, if you don’t put using statements in your headers, they have to go in the cpp-files. Maybe I could have been more explicit about that?
2: This case is more complicated.
If the header file doesn’t compile almost instantly, or if it is the convention in the project, put in the stdafx. As I said in the article, even though I don’t like what stdafx does to a project, they are often a necessary evil.
Before doing that however, it is always a good idea to think through whether you actually need access to the full definition of the type in your header. If you for instance only declare functions taking a type by pointer or reference, and not by value, you can make do with a declaration of that name. Some libraries even come with a header file containing only declarations.
My precompiled header article is more of a rant, I agree with that.