It'sPete
It'sPete

Reputation: 5211

C++ Namespace Noob Needs Assistance

I have run into some quirks about my code style that I'm hoping to fix, namely with namespace usage. Let me begin by saying that I am currently employed as the sole software engineer on my particular project and don't have access to more senior level engineers to mentor and assist me. I find this particularly worrisome since I'm concerned that I'm developing really hacky practices that will get me laughed out of the room when I attempt to change jobs in the near future.

Recently I have been following and conforming to the Google style guide. I was a bit shocked when I learned that the process I had of always doing "using namespace std;" is frowned upon. In generally, most of my projects have been relatively small with little chance for reuse of my classes. However, now that I've done more research and studying, I realize why my practice is frowned upon and I'm looking to improve the way I use namespaces and the scope operator. As a result, I have the following questions:

  1. When is it best to define a new namespace? I know that this is a weird question, and I understand that functions or variables that don't belong to a class can be group together in a namespace. However, say I have a program composed of solely classes. Is it bad practice to not define a namespace? Or should a new namespace be created solely for the project in case someone wants to interface with it later?

  2. I know this has been argued ad nauseum, but when is good to use "std::"? I ask because I recently read up on how its better to use the "wrapped" versions of the C standard libraries (e.g., cstdlib vs. stdlib.h). I changed some of my source code over to experiment. I immediately found it weird that G++ didn't yell at me for not using std::printf() instead of just printf(). The question I have now is where do I stop in terms of the explicit scope placement? For example, the compiler doesn't yell at me about size_t or uint8_t, do I have to place "std::" in front of those as well? What is considered best practice?

  3. Is it considering "ok" to call "using" on only the functions that you are using? Namely, I'm speaking to a case where I have a class and would do something like "using std::endl;" in the .cpp file that implements a particular class.

Edited to add a fourth question: 4. When writing code for a derived class, does it make sense to do "Baseclass::function()" whenever calling functions from the base class, even when the functions from the base class are not virtual and cannot be overloaded? Does this hinder or improve readability?

Thanks for all the help. I find this site to be a great resource!

Upvotes: 3

Views: 314

Answers (3)

Ben Kuhn
Ben Kuhn

Reputation: 451

These are practices that have served me well over many years. Hope you find this helpful.

1) Namespaces are an organizational technique for keeping like things together, usually for discoverability and to avoid name collisions with other code. They can be a great aid help when you're using intellisense-capable IDEs, making it easy to code without having to bounce back to docs to find something. Excessively fine-grained namespaces can be as detrimental to your code as no namespaces. While there's no hard rule here, but if you're consistently creating new namespaces for groups of less than 3-4 items, you are probably overdoing it. You also wouldn't typically define new namespaces inside a .cpp file, since that's the only file that would see it. I rarely see examples of the other extreme.

When working with templates, where everything is in headers, I like to create a "details" namespace under the main namespace to isolate the 'private' classes of the template library from the things that people are actually expected to use. There are other ways of achieving similar results that provide better encapsulation, but they are also more work to maintain.

2) Using statements should typically be isolated in C++ files, and not placed in headers, otherwise you lose track of what is 'used' pretty quickly in large projects. Similarly, it's best for portability and maintainability if your headers don't implicitly rely on using statements. You can make this easy to avoid by placing your using statements immediately after your include statements.

// main.cpp
#include "myheader1.h" // can't see using namespace std, ok.

using namespace std;

// Does this have std:: in front of everything that needs it? 
// Maybe. Compiler won't tell me...
#include "myheader2.h" 

Never put a using statement inside of an open namespace. That is, unless you really, really want to make peoples heads spin. This likely won't work like you (or the next guy) expects.

namespace A { ... }

namespace B {
  using namespace A; // Don't do it!
}

In some cases, for absolutely ubiquitous namespaces, I see people put using statements in precompiled headers (is that just a VC++ thing?). I find that tolerable because they're usually local to a smaller body of code, though even there I think it's a stretch. It can facilitate the header dependency problem mentioned above.

3) That practice can get to be a nuisance, because you'll find that you have to keep going back for 'one more thing' and it can be confusing ("Wait, for this file did I use math::vector, physics::vector or std::vector?"). If you can't use the entire namespace because of collision issues, it may just be better to be explicit about at least one of the namespaces. If there's a lot of overlap, and maybe be explicit about both.

In some rare cases, with deeply nested namespaces, it may be useful to write something like this:

using namespace this::thing::is::ridiculous::someone::should::trim::it = ludicrous;

That allows to reference the namespace with a short moniker, e.g.

auto p = new ludicrous::SomeClass();

If you are going to do that, you should establish consistent conventions throughout the codebase for the namespaces that you do that to. If you use 3 different names in 3 different places, you just make the code less readable.

Upvotes: 2

bobestm
bobestm

Reputation: 1334

My preference is to use std::cout for example, in other words ::FunctionName(). 1. In my opinion this makes the usage obvious/explicit to reviewers/readers of the code.
2. The "using namespace " ends up including all classes of that namespace and consequently may result in clashed with your class/function names. 3. If one knows that whatever one is developing is a library creating it in its own namespace is a must. 4. For classes that are not going to be developed/interfaced to third parties, I wouldn't bother with namespaces.

Let me know if this answers your question. Otherwise come back for more detail.

Upvotes: 0

Yuushi
Yuushi

Reputation: 26040

  1. Anything that is designed to be at all reusable should use a namespace. Anything that has a name that has any possibility of name clashing should use a namespace, and this means pretty much anything. With smaller projects, it matters less, but in general, everything should probably go into a namespace of some kind.

  2. Based on the C++ standard, anything that comes from a C++ standard header will be in namespace std. They may also be yanked into the global namespace. Hence, you should prefer to use std::printf or std::uint8_t and the like for maximum portability.

  3. It's a matter of preference. For basic things that are in the std:: namespace, I'd rather be explicit personally, since it's so few characters to type. For highly nested namespace names (like some parts of boost where there are 3+ namespaces to go through), then using makes more sense.

Upvotes: 2

Related Questions