Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ namespace best practice dilemma

Tags:

c++

namespaces

I'm finding that what I've considered "best practice" for use namespace in c++ is hurting the readability of my code, and making me question how to use them well.

My program consists of a few different modules which are mostly built into libraries that the "main" application uses. Each library uses it's own namespace, and their namespaces are all "inside" a project namespace to help project against name conflicts with 3rd party code. So I end up with class names such as "myproject::logging::Logger" and "myproject::reporting::ReportType" (As made up examples).

So far so good. And in my .cpp files I have no problem. I use "using myproject::logging" at the top for example, and can cleanly refer to my Logging class. In the unlikely event of a conflict between two of my namespaces I can just explicitly say which one I want. This works well.

Header files are different though. It's considered bad practice to put using statements into header files as they will affect unrelated code that may not expect them. So I always fully qualify all the names in .hpp files. That was somewhat ugly but managable up to now so I've put up with it. But now I'm increasing using template code in my libraries which means that there is much more actual code in my .hpp files now. And having to fully qualify every name is making the code practically unreadable due to the length of type names.

I'm starting to feel that the benefits of namespaces and best practice for using them are beginning to be outweighed by the unreadablilty of the code I'm having to write. I'm starting to wonder if I would be better abandoning the use of namespaces to gain the benefit of more readable code and fixing any name conflicts if and when they appear.

An alternative is to use short, single layer namespaces so instead of "myproject::logging::Logger" I would merely have "log::Logger" which would help a lot but make the likelyhood of namespace conflicts much higher, and also have the namespaces convey less useful information.

As I've said, this only really affects code in .hpp files as I'm happily using "using namespace" in my implementation files to make this manageable, but it is becoming a problem as I look at my templated code in .hpp files now and think "eww...." which can't be good :P

Anyone got any practical advice?

like image 919
jcoder Avatar asked Aug 05 '11 10:08

jcoder


People also ask

Is it good practice to use namespaces?

The statement using namespace std is generally considered bad practice. The alternative to this statement is to specify the namespace to which the identifier belongs using the scope operator(::) each time we declare a type.

Does using namespace std affect performance?

It doesn't affect the runtime performance at all.

Can I use namespace in C?

Namespace is a feature added in C++ and is not present in C. A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it. Multiple namespace blocks with the same name are allowed.


2 Answers

Here's what I do.

In <mylibrary.h>:

namespace myproject {   namespace mylibrary   {     namespace impl     {       using namespace otherlibrary;       using namespace boost;       using namespace std;       using namespace whatever::floats::your::boat;        class myclass;       class myotherclass;     };     using impl::myclass;     using impl::myotherclass;   }; }; 

In the source:

#include <mylibrary.h> using namespace myproject::mylibrary; //clean! 
like image 157
n. 1.8e9-where's-my-share m. Avatar answered Oct 04 '22 13:10

n. 1.8e9-where's-my-share m.


I have been in this situation before. It is often the case that a lot of template functions/classes in your headers are really "implementation", although by the nature of templates in C++ you are forced to put them in a header file. Thus, I just put everything in some "detail" or "implementation" namespace, where I can comfortably use "using namespace". At the end, I "drop" what people should use to the corresponding place. Like this:

namespace myproject { namespace somemodule {  namespace _implementation {  using namespace myproject::othermodule; using namespace myproject::yetanothermodule;  template <...> class some_internal_metafunction{ ... };  template <...> class stuff_people_should_use_outside { ... };  } // namespace implementation         using stuff_people_should_use_outside ; }} // namespace myproject::somemodule 

This approach might enlarge a bit the names on your compiler reports, though.

Alternatively, you can give up the modules namespaces. But it might not be a good idea for an extremely large project.

like image 33
dsign Avatar answered Oct 04 '22 12:10

dsign