是什么要求我声明"using namespace std;"?

vet*_*982 17 c++ namespaces using using-directives include

这个问题可能重复,但我找不到一个好的答案.简短而简单,需要我申报

using namespace std;
Run Code Online (Sandbox Code Playgroud)

在C++程序中?

Pét*_*rök 44

由于C++标准已被接受,实际上所有标准库都在std命名空间内.因此,如果您不想限定所有标准库调用std::,则需要添加using指令.

然而,

using namespace std;
Run Code Online (Sandbox Code Playgroud)

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

using std::string;
Run Code Online (Sandbox Code Playgroud)

  • +1因为是唯一提到它的人不满意. (14认同)

Col*_*ant 22

没有什么,它是一个简化,以避免使用std ::前缀该命名空间中的所有内容

  • 并且也被视为糟糕的做法. (12认同)
  • @GMan,@ Hassan:在实现文件中使用它非常好,在头文件中也很危险.为什么每个人都在说"糟糕的做法"?我不想在我需要输入`std ::`的代码上工作,就像我不想用`using namespace some_tools'隐式导入任何命名空间一样;` (7认同)
  • 如果你使用全局命名空间,它的做法很糟糕:D (2认同)

vis*_*tor 7

从技术上讲,您可能需要使用(对于整个名称空间或单个名称)才能使用Argument Dependent Lookup.

考虑以下两个使用的函数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);
}
Run Code Online (Sandbox Code Playgroud)

dumb_swap总是打电话std::swap- 即使我们更喜欢zzz::swap用于zzz::X对象.

smart_swap使得std::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)
);
Run Code Online (Sandbox Code Playgroud)

IMO,在这样的代码中std::只会产生线路噪声.

using namespace std;如果在实现文件中使用它,我就不会在这种情况下发现令人发指的罪行(但它甚至可以限制在函数范围内,如交换示例中所示).

绝对不要将using语句放在头文件中.原因是这会污染其他标头的名称空间,这可能包含在有问题的标头之后,可能会导致其他标头中的错误,这可能不在您的控制之下.(它还增加了一个惊喜因素:包含该文件的人可能不会期望看到所有类型的名称.)


Ale*_*ler 5

能够在std命名空间中引用成员而无需std::member显式引用.例如:

#include <iostream>
using namespace std;

...
cout << "Hi" << endl;
Run Code Online (Sandbox Code Playgroud)

#include <iostream>

...
std::cout << "Hi" << std::endl;
Run Code Online (Sandbox Code Playgroud)


Ale*_*lis 5

你绝对不应该说:

using namespace std;
Run Code Online (Sandbox Code Playgroud)

在你的C++标题中,因为这超过了使用命名空间的全部意义(这样做会构成"命名空间污染").有关此主题的一些有用资源如下:

1)stackoverflow线程on 标准约定使用"std"

2)Herb Sutter关于迁移到命名空间的文章

3)来自Marshall Cline的C++ Faq lite的FAQ 27.5.