跳转至

60 为什么不用using namespace std

为什么我个人不使用 using namespace std,这只是一种观点。

1. 什么是 using namespace

就像上文中的代码用了很多标准库的内容,如果在代码前面加上

using namespace std;

就可以直接写 vector,find_if 了,看上去代码更干净一点。 还可以把它限制在作用域中,比如写到 main 函数的第一行,这样 main 函数中调用标准库就不用写”std::“了。

所以using namespace可以非常有用,如果你在处理很长的命名空间,或是你有自己的命名空间,自己的项目文件中的符号都在这个命名空间中,你可以使用这个。

但是我个人不喜欢using namespace std

2. 为什么不喜欢

第一眼看上去代码是干净了,但是如果看原始代码,可以发现你很容易就能指出代码中使用的是 C++标准模板库(带有 std 前缀的)。如果用了using namespace std,就相对而言有点难分辨了。如果你也用标准库喜欢用的snake case(蛇形命名法,如 find_if),就很难区分到底是不是 std 中的。

展示一个生活中的真实例子吧。Cherno 当时在 EA 的寒霜引擎部门工作,它们使用的是 EASTL(C++ STL 的替换),用的是 eastl 的命名空间,那如果你只写vector,我怎么知道这是在用eastl::vector还是std::vector呢?

namespace apple{

    void print(const std::string& text)
    {
        std::cout << text << std::endl;
    }
}

using namespace apple;
int main()
{
    // apple::print("Hello");
    print("Hello");

又有一个新的命名空间 orange,其中也有一个 print 函数,不过是打印反转的内容。

namespace orange{
    void print(const char* text)
    {
        std::string temp = text;
        std::reverse(temp.begin(),temp.end());
        std::cout << temp << std::endl;
    }
}

using namespace apple;
using namespace orange;

int main()
{
    print("Hello");

那这里哪一个会被调用呢?

这并不是 orange 在 apple 后导致的,而是因为其它原因。“Hello”其实是一个 const char[]数组,而不是一个 string,如果只有 apple 命名空间,会在 apple::print()中做一个隐式转换,将 const char 数组转换为 string 对象。但是引入 orange 命名空间后,orange::print()匹配度更高,因为它的参数本来就是一个 const char*,不需要隐式转换。

如果我们不用using namespace,而是简单地引入另一个库apple::print()就不会有这样的运行时错误。

另一个要百分百避免的就是在头文件中使用 using namespace,永远不要这样做,把这些命名空间用在了你原本没有打算用的地方,谁知道它会 include 什么呢?任何大型项目中追踪起来都是很困难的,所以绝对不要在头文件中使用 using namespace!