Why is “using namespace std” considered bad practi

2019-05-21 08:00发布

I've been told by others that writing using namespace std in code is wrong, and that I should use std::cout and std::cin directly instead.

Why is using namespace std considered a bad practice? Is it inefficient or does it risk declaring ambiguous variables (variables that share the same name as a function in std namespace)? Does it impact performance?

30条回答
一夜七次
2楼-- · 2019-05-21 08:15

I agree with the others here, but would like to address the concerns regarding readability - you can avoid all of that by simply using typedefs at the top of your file, function or class declaration.

I usually use it in my class declaration as methods in a class tend to deal with similar data types (the members) and a typedef is an opportunity to assign a name that is meaningful in the context of the class. This actually aids readability in the definitions of the class methods.

//header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

and in the implementation:

//cpp
Lines File::ReadLines()
{
    Lines lines;
    //get them...
    return lines;
}

as opposed to:

//cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    //get them...
    return lines;
}

or:

//cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    //get them...
    return lines;
}
查看更多
狗以群分
3楼-- · 2019-05-21 08:16

The problem with putting using namespace in the header files of your classes is that it forces anyone who wants to use your classes (by including your header files) to also be 'using' (i.e. seeing everything in) those other namespaces.

However, you may feel free to put a using statement in your (private) *.cpp files.


Beware that some people disagree with my saying "feel free" like this -- because although a using statement in a cpp file is better than in a header (because it doesn't affect people who include your header file), they think it's still not good (because depending on the code it could make the implementation of the class more difficult to maintain). This FAQ topic says,

The using-directive exists for legacy C++ code and to ease the transition to namespaces, but you probably shouldn’t use it on a regular basis, at least not in your new C++ code.

The FAQ suggests two alternatives:

  • A using-declaration:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • Just typing std::

    std::cout << "Values:";
    
查看更多
Summer. ? 凉城
4楼-- · 2019-05-21 08:16

A concrete example to clarify the concern. Imagine you have a situation where you have 2 libraries, foo and bar, each with their own namespace:

namespace foo {
    void a(float) { /* does something */ }
}

namespace bar {
    ...
}

Now let's say you use foo and bar together in your own program as follows:

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

At this point everything is fine. When you run your program it 'does something'. But later you update bar and let's say it has changed to be like:

namespace bar {
    void a(float) { /* does something completely different */ }
}

At this point you'll get a compiler error:

using namespace foo;
using namespace bar;

void main() {
    a(42);  // error: call to 'a' is ambiguous, should be foo::a(42)
}

So you'll need to do some maintenance to clarify which 'a' you meant (i.e. foo::a). That's probably undesirable, but fortunately it is pretty easy (just add foo:: in front of all calls to a that the compiler marks as ambiguous).

But imagine an alternative scenario where bar changed instead to look like this instead:

namespace bar {
    void a(int) { /* does something completely different */ }
}

At this point your call to a(42) suddenly binds to bar::a instead of foo::a and instead of doing 'something' it does 'something completely different'. No compiler warning or anything. Your program just silently starts doing something complete different than before.

When you use a namespace you're risking a scenario like this, which is why people are uncomfortable using namespaces. The more things in a namespace the greater the risk of conflict, so people might be even more uncomfortable using namespace std (due to the number of things in that namespace) than other namespaces.

Ultimately this is a trade-off between writability vs reliability/maintainability. Readability may factor in also, but I could see arguments for that going either way. Normally I would say reliability and maintainability are more important, but in this case you'll constantly pay the writability cost for an fairly rare reliability/maintainability impact. The 'best' trade-off will determine on your project and your priorities.

查看更多
孤傲高冷的网名
5楼-- · 2019-05-21 08:16

"Why is 'using namespace std;' considered a bad practice in C++?"

I put it the other way around: Why is typing 5 extra chars is considered cumbersome by some?

Consider e.g. writing a piece of numerical software, why would I even consider polluting my global namespace by cutting general "std::vector" down to "vector" when "vector" is one of the problem domain's most important concepts?

查看更多
\"骚年 ilove
6楼-- · 2019-05-21 08:18

This is a bad practice, often known as global namespace pollution. Problems may occur when more than one namespace has the same function name with signature, then it will be ambiguous for the compiler to decide which one to call and this all can be avoided when you are specifying the namespace with your function call like std::cout . Hope this helps. :)

查看更多
太酷不给撩
7楼-- · 2019-05-21 08:21

It doesn't make worse your software or project performance, the inclusion of the namespace at the beginning of your source code isn't bad. The inclusion of the using namespace std instruction varies according to your needs and the way you are developing the software or project.

The namespace std contains the C++ standard functions and variables. This namespace is useful when you often would use the C++ standard functions.

As is mentioned in this page:

The statement using namespace std is generally considered bad practice. The alternative to this statement is to specify the namespace to which the identifier belongs using the scope operator(::) each time we declare a type.

And see this opinion:

There is no problem using "using namespace std" in your source file when you make heavy use of the namespace and know for sure that nothing will collide.

Some people had said that is a bad practice to include the using namespace std in your source files because you're invoking from that namespace all the functions and variables. When you would like to define a new function with the same name as another function contained in the namespace std you would overload the function and it could produce problems due to compile or execute. It will not compile or executing as you expect.

As is mentioned in this page:

Although the statement saves us from typing std:: whenever we wish to access a class or type defined in the std namespace, it imports the entirety of the std namespace into the current namespace of the program. Let us take a few examples to understand why this might not be such a good thing

...

Now at a later stage of development, we wish to use another version of cout that is custom implemented in some library called “foo” (for example)

...

Notice how there is an ambiguity, to which library does cout point to? The compiler may detect this and not compile the program. In the worst case, the program may still compile but call the wrong function, since we never specified to which namespace the identifier belonged.

查看更多
登录 后发表回答