C++ Standard Library: How to write wrappers for cout, cerr, cin and endl?
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?
Alex has given you an answer how to syntactically solve that problem. However, I want to point out two other arguments regarding this issue:
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 typestd::
compared to spending half a night debugging to find out your code calledstd::distance()
instead of your owndistance()
function, just because you made a small mistake andstd::distance()
accidentally is a better match.-
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 thestd::
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 bothusing
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 findstd::
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 anyusing
directive or declaration in their code. (The only exception to that rule isusing std::swap
, BTW, which you'll need in order to haveswap(a,b)
pick up overloads outside of namespacestd
.) Once they got used to it, they didn't mind and, when asked about it, they said they find code without thestd::
prefix confusing. Some even added thestd::
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.
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.