5

Based on advice here (Why is "using namespace std" considered bad practice?), I'm avoiding using namespace std;. However, based on what it says in Section 3.1 of C++ Primer, I have been making declarations individually, as in:

using std::cout;
using std::cin;
using std::setw;
using std::setprecision;

Assuming this is considered an acceptable practice, is there a compact way to state all of this on one line? I know I could do:

using std::cout; using std::cin; using std::setw; using std::setprecision;

but that is not particularly compact. I tried the following, in the spirit of how it works when defining variables:

using std::cout, std::cin, std::setw, std::setprecision;

But my compiler throws an exception.

If my assumption is wrong (i.e., if using std::cout; is not good practice), then that may actually be the answer. I am certainly open to this, as I don't want to encourage or write smelly code..

eric
  • 7,142
  • 12
  • 72
  • 138
  • 6
    Best way: use `std::cout` directly. – llllllllll Mar 01 '18 at 16:50
  • Why not `using namespace std`? – Jean-Baptiste Yunès Mar 01 '18 at 16:51
  • 1
    @Jean-BaptisteYunès : https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – eric Mar 01 '18 at 16:51
  • @liliscent I will update question with implicit question: is it bad to do this? – eric Mar 01 '18 at 16:52
  • 4
    @neuronet IMHO, it's not bad, but unnecessary. Once you are used to writing it explicitly, `std::cout` is more natural, an isolated `cout` looks very strange. – llllllllll Mar 01 '18 at 16:55
  • @liliscent But sometime we have no other choice in order to get a default definition in case where there would be no overload: `using std::begin; for(auto beg = begin(container);...` – Oliv Mar 01 '18 at 16:58
  • @liliscent I know that, but IMHO that should not be took as an absolute advice to apply in every programming context. Same for gotos... – Jean-Baptiste Yunès Mar 01 '18 at 17:00
  • @liliscent thanks that is actually very useful to know that it would be considered a code smell. It must be obvious I am new to c++ (I am coming from Python). – eric Mar 01 '18 at 17:02

2 Answers2

1

Don't fight the language, work with it.

And the advice you've thus received is incomplete, don't ever pollute whatever namespace you're currently in by bringing std into it, even bit by bit. Doing so can even introduce subtle bugs centred around overload resolution. Tutorials only do it so pupils can see the wood from the trees.

As for efficiency, this point is moot as there will be no effect at all on the compiled program in writing, for example, std::cout or cout.

Of course, C++ does provide you a way of achieving your notion of typographic elegance. It is, after all, probably the most powerful language developed to date. You could build a variadic macro that achieves what you want and the use at the calling site would be make_elegant(cout, cin, setw, setprecision).


An example of the overload point:

#include <iostream>
// see what happens if you put using namespace std; here.
template<typename T>
T max(T& a, T& b)
{
    std::cout << "Next week's lottery numbers are";
    return a > b ? a : b;
}

int main() {
    const int a = 5;
    const int b = 6;
    max(a, b);
}

Here, the program behaviour will change substantially if you write using namespace std; or using std::max; since std::max is a better match for the parameters then the max I built.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Thanks this is very helpful I am newly picking up C++ from Python, and it is very useful to know what would be considered a code smell by more experienced developers. Now I'm just wondering how to change my title to make it a better question. – eric Mar 01 '18 at 17:03
0

This is C++17 https://en.cppreference.com/w/cpp/language/namespace#Using-declarations

namespace X
{
    using ::f;        // global f is now visible as ::X::f
    using A::g;       // A::g is now visible as ::X::g
    using A::g, A::g; // (C++17) OK: double declaration allowed at namespace scope
}

in your case, this works with c++ >= 17

#include <iostream>
#include <string>
#include <unordered_map>
using std::cout, std::string;

int main() {
  // using std::cout, std::string;  // here also ok.
  auto m = std::unordered_map<string, int>{{"1", 2}, {"3", 4}};
  for (auto &&[k, v] : m) {
    cout << k << " " << v << "\n";
  }
  return 0;
}
AsukaMinato
  • 1,017
  • 12
  • 21