Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Standard Library: How to write wrappers for cout, cerr, cin and endl?

Tags:

c++

iostream

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?

like image 585
Ashwin Nanjappa Avatar asked May 21 '10 04:05

Ashwin Nanjappa


2 Answers

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.

like image 28
Alex Martelli Avatar answered Sep 25 '22 22:09

Alex Martelli


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.

like image 129
sbi Avatar answered Sep 23 '22 22:09

sbi