2

For example, I know I will only need "cout" from the std namespace in my code, so I'll refer to it as:

using std::cout;

So I can freely use it as:

cout << "Using namespaces like a boss!" << std::endl;

Instead of bringing the whole namespace to my code.

I'm very used to typing everything prepending std as I was told using the namespace was kind-of a bad practice as it can cross with other functions in other namespaces (Fortunately, it has not been the case for me, I'm still learning to code and I'm in second semester of my career), but instead of prepending std to everything, I'd like to do "using std::cout" and other stuff like that so I can improve readability in my code, which is important for me to understand my code later at some point in time.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Darktega
  • 123
  • 8
  • Isn't the syntax just `using std::cout;`? `using namespace std::cout;` would be for if `std::cout` was a namespace, which it isn't. – user2357112 Dec 21 '15 at 04:17
  • `using namespace std::cout;` won't compile, since `cout` is not a namespace. Thus, I doubt this is the actual line you are using in your code. – Igor Tandetnik Dec 21 '15 at 04:17
  • Oh, right! Thanks for noting it, it's just a slip. – Darktega Dec 21 '15 at 04:18
  • I don't think anyone would say that using a `using` directive, even for just a single type, is a bad practice, that's a pretty strict view of the language feature. That said I wouldn't say that `cout` is substantially easier to read than `std::cout`, and usually it only appears once in a line. IMO it's also about the scope. If you do it at file scope it's much more problematic than doing it in the scope of a single function, or even a scope block within a function. I'm usually willing to any kind of using directive in that scenario, personally. – Chris Beck Dec 21 '15 at 04:27

2 Answers2

5

It is a bad practice to universally label things a "bad practice" as a substitute for discussing the real problems and trade-offs.

Some techniques can be bad and are misused often. The using and especially using namespace directives can be misused, so a cookie-cutter mindset is to just say they are somehow "bad".

Inside a single .cpp file, you have more control over the namespace(s), so using std::cout at the file scope or even using namespace my_funny_namespace is fine as long as the opportunities for clashes are manageable and there is some gain in readability. At some point, perhaps if the .cpp file gets complex, you run the risk that a new name gets added to some_funny_namespace that clashes with one of your names and using namespace some_funny_namespace would bring in something that would break your code. But this might be less likely with something stable like boost or std.

You can also use using locally, per-function. But if most functions in the file need the same declaration, D.R.Y.

Where it can cross the line into a really bad thing is when you use either of these in a header. Then you have leaked names from another namespace into every file that includes your header too. See this great answer for alternatives and discussion. This is really bad because it can cause spooky action-at-a-distance bugs when including or not-including a header causes some completely unrelated problem to show up or disappear. And it isn't just "your" code that might break, it could break someone else's code that uses your header.

Don't leak names into other namespaces

So using and especially using namespace is verbotten in headers? What if the header is for internal use within a select set of .cpp files? Then, maybe it's OK. That's the problem with cookie-cutter rules, there is always an exception and making some hypothetical thing worse for no reason but best-practices is terrible.

The upside to using is readability (which should not be under-rated).

The downside is the potential for name clashes, especially unpredictable ones in some other random code.

Choose wisely. Carefully considering all aspects of your design is the good practice.

(and asking good questions isn't too bad either).

Community
  • 1
  • 1
Anders
  • 2,270
  • 11
  • 19
  • Thanks for your answer and suggestion about asking questions. I often forget that programming isn't about absolutes so I just went ahead and asked as if this was something of obligatory use for good programming. That's just a premature actitude of an early programmer as me. I'll probably use namespaces so I can improve readabilty in my own code from school exercises, but definitely not in big projects or similar so I don't get any leaks from my headers. Now I have a grasp of what to do thanks to your answer. :) – Darktega Dec 21 '15 at 06:12
  • You are welcome. FWIW, I was not implying you had the "cookie-cutter" mentality, ironically I was worried more about the advice you were given. But rules-of-thumb are good too, if it was shorthand for the long answer. Nice discussion. – Anders Dec 21 '15 at 06:22
1

usingnamespace::identifier; is part of the language because in some programs it's helpful. You're balancing concision and flexibility against fragility, but the worst that can happen is you have to step in to resolve a compiler error by disambiguating which cout object you mean. If you're just using a handful of identifiers from a large namespace, having targeted using statements is often a reasonable compromise; if the list starts to get overly large then using namespace std; may become easier.

Neither should be used in at file scope in a library's header file, as they'll stay in affect for the rest of the translation unit and make break client programs.

Within confining scopes, and within implementation files (.cpp, .cc or whatever extension you use), you can basically afford to experiment with using and fix ambiguities as necessary - you'll learn what works best for you.

using std::begin; and using std::end; are good examples of particularly useful using statements, as they allow begin(my_container) to match std::begin() when the latter has an overload for my_container, but if my_container's begin is actually in whatever namespace the container's declared in, begin() can still match due to Argument Dependent Lookup.

Tip: it's usually better to write [std::]cout << "Using namespaces like a boss!\n"; - more concise, and why force flushing? It tends to degrade performance, and cout is tied to cin so flushing will happen when needed for prompting for user input....

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252