17

I do not like using namespace std, but I am also tired of having to type std:: in front of every cout, cin, cerr and endl. So, I thought of giving them shorter new names like this:

// STLWrapper.h

#include <iostream>
#include <string>

extern std::ostream& Cout;
extern std::ostream& Cerr;
extern std::istream& Cin;
extern std::string&  Endl;

// STLWrapper.cpp

#include "STLWrapper.h"

std::ostream& Cout = std::cout;
std::ostream& Cerr = std::cerr;
std::istream& Cerr = std::cin;
std::string _EndlStr("\n");
std::string& Endl = _EndlStr;

This works. But, are there any problems in the above which I am missing? Is there a better way to achieve the same?

MSalters
  • 173,980
  • 10
  • 155
  • 350
Ashwin Nanjappa
  • 76,204
  • 83
  • 211
  • 292
  • 16
    This is only OK if you are a one man company and nobody else will ever read the code. Shortcuts like this only serve to make the code obfuscated and is rarely a good idea for a team of developers. – Martin York May 21 '10 at 10:27
  • Martin: Point noted. Yes, this may not be a good idea when code will be used with other people. – Ashwin Nanjappa May 21 '10 at 10:29
  • The `std::string& Endl` defined here has different functionality than `std::endl` which attempts to flush the buffer. – AnotherParker Apr 01 '15 at 16:38

2 Answers2

84

Alex has given you an answer how to syntactically solve that problem. However, I want to point out two other arguments regarding this issue:

  1. No matter whether you're employing a using directive (using namespace std) or its lesser evil sister, a using declaration (using std::cout), overloading might lead to nasty surprises. It's not much hassle to type std:: compared to spending half a night debugging to find out your code called std::distance() instead of your own distance() function, just because you made a small mistake and std::distance() accidentally is a better match.

  2. A line of code gets written once, but - depending on its lifetime - it is read tens, hundreds, and some even thousands of times. So the time it takes to write a line of code simply doesn't matter at all, important is only the time it takes to read and interpret a line of code. Even if it takes three times as long to write a line with all the proper std:: in place, if it makes reading it only 10% faster, it is still worth the trouble.
    So the important question is: Is it easier to read and interpret a line of code with all the std:: in place or is it harder? From another answer:

    Here's one more data point: Many, many years ago, I also used to find it annoying having to prefix everything from the standard library with std::. Then I worked in a project where it was decided at the start that both using directives and declarations are banned except for function scopes. Guess what? It took most of us very few weeks to get to used to write the prefix and after a few more weeks most of us even agreed that it actually made the code more readable. (There's a reason for that: Whether you like shorter or longer prose is subjective, but the prefixes objectively add clarity to the code. Not only the compiler, but you, too, find it easier to see which identifier is referred to.)

    In a decade, that project grew to have several million lines of code. Since these discussions come up again and again, I once was curious how often the (allowed) function-scope using actually was used in the project. I grep'd the sources for it and only found one or two dozen places where it was used. To me this indicates that, once tried, developers didn't find std:: painful enough to employ using directives even once every 100kLoC even where it was allowed to be used.

    I think it's sad that every book and tutorial you'll find skips std::, because that makes people getting used to read the code that way. When I taught C++ for several years (after the above mentioned experience), I told my students that I don't want to see any using directive or declaration in their code. (The only exception to that rule is using std::swap, BTW, which you'll need in order to have swap(a,b) pick up overloads outside of namespace std.) Once they got used to it, they didn't mind and, when asked about it, they said they find code without the std:: prefix confusing. Some even added the std:: prefix to code they typed from a book or tutorial which didn't have it.

Bottom line: What's so hard about typing std:: that everybody gets so worked up about it? By now I have been doing it for >15 years, and I don't miss using at all.

Community
  • 1
  • 1
sbi
  • 219,715
  • 46
  • 258
  • 445
  • 4
    Sbi: I have to admit that I was influenced early on by code from books or other sources that used "using". I might have been a bit influenced by similar directives in Java & Python. After pondering about your reasoning (and seeing no better alternative), I have decided to fix the code to use std:: all over the place. Thanks for taking the time on a detailed reply :-) – Ashwin Nanjappa May 21 '10 at 10:39
  • 5
    +1 (I wish I could do more) for "A line of code gets written once, but - depending on its lifetime, it is read tens, hundreds, and some even thousands of times. So the time it takes to write a line of code simply doesn't matter at all, important is only the time it takes to read a line and interpret of code." -- So True but so difficult to convince this to coworkers. – Arun May 24 '10 at 07:44
  • +1 Great argument. Count me as another convert. I'm adding 'using' to my list of verboten mechanisms along with arrays, global variables, macros, if-then-elseif-elseif-elseif... monstrosities, etc. – Amardeep AC9MF Jun 02 '10 at 11:20
  • 3
    Hum, didn't see that. I am also convinced that prefixing adds clarity, especially when namespaces and subfolders match, so that you know which include brought that particular object :) – Matthieu M. Aug 27 '10 at 16:42
  • 2
    @sbi Some (majority) of the designers of C++ thought that typing std:: and other namespaces, may be not only hard but can make code harder to read. That's why they "invented" using declaration and using directive. And I'm sorry but when someone asks me what's hard about typing five more chars everytime you use standard library I just can't stand it. In code as you're saying with over few million lines probably good few thousands of extra/surplus chars has been typed. Time to type it could be spend to do more useful things. And why do you think now in new standard they use auto? – There is nothing we can do Feb 09 '11 at 09:56
  • Namespace directives at function scope are really useful whenever you use `boost` or ``. I wholeheartedly agree with everything you say though. – Alexandre C. Feb 09 '11 at 10:10
  • @sbi continue I'm not saying that one never should use fully scoped name of a obj but with such a famous objs like cin, cout and cerr it is a bit overdoing. – There is nothing we can do Feb 09 '11 at 10:11
  • @There: "Whether you like shorter or longer prose is subjective, but the prefixes objectively add clarity to the code." There is nothing I could add. – sbi Feb 09 '11 at 12:34
  • @Alexandre: Using declarations at function scope _was allowed_ in that project. Yet, it was used very little. OTOH, none of those placeholder stuff was ever used, so I guess you have a point. – sbi Feb 09 '11 at 12:36
  • @sbi "the prefixes objectively add clarity to the code." - not according to Bjarne, me and tons of other people. – There is nothing we can do Feb 09 '11 at 14:37
  • 1
    @There: When it comes to code, the only really objective judge is the compiler and the compiler agrees with me which one is less ambiguous. BTW, Stroustrup _did_ get some things wrong, even according to his own, later, judgment (just think of implicit conversion operators or the term "RAII") and I have indeed found myself disagreeing with him once in a while over the last decades. So I'm not impressed by his name (especially so when used without citation). OTOH, I wager that, out of the regulars in SO's `c++` tag, considerably more rep will be in favor of my POV regarding this than against it. – sbi Feb 09 '11 at 15:34
  • 4
    @There is nothing we can do: `auto` is not there to reduce typing, but to create variables of types for which you cannot spell the name. It just happens that you can use it to reduce typing, but the main functionality that it adds is being able do write this: `auto lambda = [](int x){ return x*x; };`, that would not be possible to do without `auto`. – David Rodríguez - dribeas Feb 09 '11 at 17:28
  • @sbi I don't really care how many people from SO will agree with you on that and how many won't. This is not the point. The point is that by using std:: to cin, cout and cerr you making your code less readable. Every mentaly healty c++ programmer knows that cout etc are "almost forbidden" to be used as names within user code. And I'm not saying that Bjarne is always right or that he never makes mistakes but he has more experience than you on working on big/important projects so I take his words not yours where comes to good programming practice and style. – There is nothing we can do Feb 09 '11 at 19:04
  • sbi continue but, I repeat: I'm not saying that fully scoped names are bad or wrong. Yes they are necessary but in cases of such megastars like cout, cin and cerr definitely not (according to Bjarne, me and tons of others). – There is nothing we can do Feb 09 '11 at 19:06
  • @David no, you're wrong. auto is introduced not only for the (valid) reason you've described but also to remove unnecessary clatter from definitions like this: vector>>> v;//initialize and get iterator i = v.begin(). And you are also wrong saying that auto isn't re-introduced to reduce typing. That's exactly one of the main reason why auto is re-introduced. Another reason for re-introducing this keyword is for situations when you cannot now in advance what type the variable will have.So yes, you are wrong. www.nuonsoft.com/blog/2009/06/08/auto-keyword-in-visual-c-2010/ – There is nothing we can do Feb 09 '11 at 19:17
  • 1
    @There: That quote from Bjarne seems to support David's statement. As for making a fool - I've flagged your last two comments as offensive. – sbi Feb 09 '11 at 20:05
  • @sbi go on Bjarne's web page check what does he has to say about auto and what for it was reinvented and then make a comment and decide what it seems Bjarne to have in mind not some David. – There is nothing we can do Feb 09 '11 at 20:41
  • 9
    @There: You might have realized that your last two comments towards David disappeared after I flagged them for being offensive. This is not the first time I've seen this happen to you. And it's the moment I will stop this discussion with you. I have learned to respect David's insights and I enjoy discussing with him, because I learn a lot from doing so. You, OTOH, are not discussing to gain new insights, you're just discussing to prove your point, and will therefore get angry if the discussion doesn't go your way. I can do very well without wasting my time on that. Have a nice day. – sbi Feb 09 '11 at 21:17
  • @sbi I am not here to discuss things. It's not a discussion forum. When someone talks rubbish (like he did about auto) I just correct such person. And do I have to prove my point? Wait a sec, it's not my point it's Bjarne's point, you know. And after reading Bjarne's reasoning are you still convinced that what Bjarne says supports David's statement? David knew that there are bells ringing but wasn't sure in which church. – There is nothing we can do Feb 10 '11 at 06:51
  • @sbi "The Design and Evolution of C++" 17.4.1 paragraph 5. And as I've said Bjarne has light years more of experience and knowledge about C++ than you so every reasonable person will follow his advice. – There is nothing we can do Feb 16 '11 at 07:08
  • so as i pointed out above, Bjärne is like Chuck Norris but with just a bit less hair – lurscher Nov 08 '11 at 20:12
  • @lurscher: I have no idea what you are referring to. (Nor do I know some Bjärne.) – sbi Nov 09 '11 at 10:15
  • 2
    Actually, the whole reason namespaces were introduced was to get rid of unneccesary prefixes. Otherwise simply calling the streams `std_cin`, `std_cout` and `std_cerr` and reserving every name starting with `std_` for the implementation would have done the trick. – celtschk Nov 15 '11 at 17:14
  • 1
    I am just getting started in Visual C++ (experienced with C#) ...this is good information and I can see the harm in getting too comfortable with `using` and how horrible ambiguities can burrow themselves deep in your code. I'll take this advice to heart ... +1!!! – IAbstract May 26 '12 at 22:48
  • You have convinced me that `using` is best avoided. However, you have also convinced me that good c++ code is often ugly and obnoxious. – Z boson Oct 26 '14 at 15:34
  • @Zboson: Beauty is in the eye of the beholder. Clarity is objective. – sbi Oct 26 '14 at 17:11
  • @sbi, I guess this fixes a problem in C https://stackoverflow.com/questions/26524776/some-one-can-explain-this-behavior-just-2-lines-of-code – Z boson Oct 27 '14 at 09:39
60

Why not

using std::cin;
using std::cout;

and so on? Then in your code you can use cin, cout, and so on, without accidentally injecting all of the rest of the std namespace into your code.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 1
    [hand to head] I was not even aware that "using" can be used with non-namespace entities! Thanks! :-) – Ashwin Nanjappa May 21 '10 at 04:42
  • 8
    @Ashwin: `using namespace_name::identifier` is called a "namespace declaration", whereas `using namespace_name` is called a "namespace directive". – sbi May 21 '10 at 06:30
  • Sbi: Thanks so much for that! I am now going back to the books to read all about "using". – Ashwin Nanjappa May 21 '10 at 10:31
  • 1
    @Ashwin: Once you're reading up `using`, it can also be used to bring a base class identifier into a derived class' scope, so that it is considered for overload resolution, or to make a private base's identifier accessible in a derived class' interface. However, I haven't really seen those in the wild. – sbi May 23 '10 at 22:06