什么情况下需要使用 "using namespace std;" 声明?

17

这个问题可能是一个重复的问题,但我找不到一个好的答案。简而言之,我需要声明什么?

using namespace std;

C++程序中怎么用?

12个回答

44

自C++标准被接受以来,几乎所有的标准库都在std命名空间内。因此,如果您不想在所有标准库调用前加上std::,则需要添加using指令。

然而,

using namespace std;

这被认为是一种不好的做法,因为你实际上导入了整个标准命名空间,从而为名称冲突开启了许多可能性。最好只导入你在代码中实际使用的东西,例如

using std::string;

我能否在一行中包含多个std元素,比如:using std::string, std::make_shared; - Akay

22

没有什么作用,它是一种简写,避免在该命名空间中的所有内容前缀都加上std::。


13
也被认为是一种不良惯例。 - GManNickG
2
如果您在全局命名空间中这样做,那是很糟糕的实践:D - Hassan Syed
7
@GMan, @Hassan:在实现文件中使用它是完全可以的,但在头文件中使用则很危险。为什么每个人都说“这是不好的做法”?我不想在需要到处输入 std:: 的代码上工作,就像我不想使用 using namespace some_tools; 隐式导入任何名称空间一样。 - Potatoswatter
1
这样做是不好的实践,因为它更可能会导致名称冲突。最好一次只导入一个符号:例如 using std::string - Matthieu M.

7

从技术上讲,你可能需要使用using(用于整个命名空间或单个名称)才能使用参数相关查找。

考虑下面两个使用swap()的函数。

#include <iostream>
#include <algorithm>

namespace zzz
{
    struct X {};


void swap(zzz::X&, zzz::X&) 
{
    std::cout << "Swapping X\n";
}
}

template <class T>
void dumb_swap(T& a, T& b)
{
    std::cout << "dumb_swap\n";
    std::swap(a, b);
}

template <class T>
void smart_swap(T& a, T& b)
{
    std::cout << "smart_swap\n";
    using std::swap;
    swap(a, b);
}

int main()
{
    zzz::X a, b;
    dumb_swap(a, b);
    smart_swap(a, b);

    int i, j;
    dumb_swap(i, j);
    smart_swap(i, j);
}

dumb_swap总是调用std::swap - 尽管我们更愿意为zzz::X对象使用zzz::swap

smart_swapstd::swap作为后备选择可见(例如,当使用整数调用时),但由于它没有完全限定名称,因此zzz::swap将通过ADL用于zzz::X


主观上,迫使我使用using namespace std;的原因是编写使用各种标准函数对象等的代码。

//copy numbers larger than 1 from stdin to stdout
remove_copy_if(
    std::istream_iterator<int>(std::cin), std::istream_iterator<int>(),
    std::ostream_iterator<int>(std::cout, "\n"),
    std::bind2nd(std::less_equal<int>(), 0)
);

在像这样的代码中,std::只会造成干扰。

如果在实现文件中使用using namespace std;,我不认为这是可恶的犯罪行为(但它甚至可以被限制在函数范围内,例如swap示例中)。

绝对不要将using语句放入头文件中。原因是这会为其他可能在问题文件之后被包含的头文件污染命名空间,可能导致其他无法控制的头文件出现错误。(这也增加了惊喜因素:包括文件的人可能没有预料到所有种类的名称都是可见的。)


5

可以直接引用std命名空间中的成员,而不需要显式地引用std::member。例如:

#include <iostream>
using namespace std;

...
cout << "Hi" << endl;

对比。

#include <iostream>

...
std::cout << "Hi" << std::endl;

5

你绝对不应该说:

using namespace std;

在您的 C++头文件中,不要使用using namespace指令,因为这违背了使用命名空间的初衷(这样做将构成“命名空间污染”)。关于此主题的一些有用资源如下:
1)stackoverflow线程,使用“std”的标准约定 2)由Herb Sutter撰写的文章,迁移至命名空间 3)Marshall Cline的C ++ Faq lite中的 FAQ 27.5

3
首先,在 C 语言中从不需要使用 using 指令,因为 C 不支持命名空间。
在 C++ 中实际上也并非必须使用 using 指令,因为任何在命名空间中的项都可以通过在前面加上 std:: 的方式直接访问。例如:
using namespace std;
string myString;

等同于:

std::string myString;

是否选择使用它是个人喜好问题,但为了省几次按键而暴露整个 std 命名空间通常被认为是不好的形式。一种替代方法仅暴露命名空间中特定的项,如下所示:

using std::string;
string myString;

这可以让你仅暴露你特别需要的std命名空间中的项,而不会意外地暴露你不想要的东西。

3

首先,C语言中不需要这样做 - C语言没有命名空间。在C++中,任何位于std命名空间中的内容都包括大部分标准库。如果您不这样做,您必须显式地访问命名空间的成员,如下所示:

std::cout << "I am accessing stdout" << std::endl;

1

命名空间是一种包装代码以避免混淆和名称冲突的方法。例如:

文件 common1.h:

namespace intutils
{
    int addNumbers(int a, int b)
    {
        return a + b;
    }
}

使用文件:

#include "common1.h"    
int main()
{
    int five = 0;
    five = addNumbers(2, 3); // Will fail to compile since the function is in a different namespace.
    five = intutils::addNumbers(2, 3); // Will compile since you have made explicit which namespace the function is contained within.

    using namespace intutils;
    five = addNumbers(2, 3); // Will compile because the previous line tells the compiler that if in doubt it should check the "intutils" namespace.
}

所以,当你写 using namespace std 时,你只是告诉编译器如果不确定应该在 std 命名空间中查找函数等定义,这通常在示例(和生产)代码中使用,因为它使得输入常见的函数如 cout 比完整限定每个函数都是 std::cout 更快捷。

0

除非你是C++标准库的实现者,并且想要避免在“新”和“旧”风格的头文件中声明代码重复,否则没有任何需要你做的事情:

// cstdio
namespace std
{
  // ...
  int printf(const char* ...);
  // ...
}

.

// stdio.h
#include <cstdio>
using namespace std;

当然,这个例子有些牵强附会(你同样可以使用普通的<stdio.h>并将其全部放在<cstdio>中),但Bjarne Stroustrup在他的The C++ Programming Language一书中展示了这个例子。


0

C++标准库中的所有文件都在std命名空间中声明其所有实体。
例如:要使用iostream中定义的cin,cout

替代方案:

using std::cout;
using std::endl;
cout << "Hello" << endl;

std::cout << "Hello" << std::endl;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接