【发布时间】:2011-01-14 03:48:42
【问题描述】:
这个问题可能是重复的,但我找不到一个好的答案。简简单单,需要我声明什么
using namespace std;
在 C++ 程序中?
【问题讨论】:
标签: c++ namespaces include using using-directives
这个问题可能是重复的,但我找不到一个好的答案。简简单单,需要我声明什么
using namespace std;
在 C++ 程序中?
【问题讨论】:
标签: c++ namespaces include using using-directives
自从 C++ 标准被接受以来,几乎所有的标准库都在 std 命名空间内。因此,如果您不想使用 std:: 限定所有标准库调用,则需要添加 using 指令。
然而,
using namespace std;
被认为是一种不好的做法,因为您实际上是在导入整个标准命名空间,从而为名称冲突提供了很多可能性。最好只导入你在代码中实际使用的东西,比如
using std::string;
【讨论】:
什么都不做,这是避免在该命名空间中的所有内容前加上 std:: 前缀的简写:
【讨论】:
std:: 的代码,就像我不想使用using namespace some_tools; 隐式导入任何命名空间一样
using std::string。
从技术上讲,您可能需要使用 using(对于整个命名空间或单个名称)才能使用 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);
}
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)
);
IMO,在这样的代码中 std:: 只会产生线路噪音。
如果在实现文件中使用using namespace std;,在这种情况下我不会发现它是令人发指的罪行(但它甚至可以被限制在函数范围内,就像在交换示例中一样)。
绝对不要将 using 语句放在头文件中。原因是这会污染其他标头的名称空间,这些标头可能包含在有问题的标头之后,可能导致其他标头中的错误可能不受您的控制。 (它还增加了令人惊讶的因素:包括该文件的人可能不希望看到所有类型的名称。)
【讨论】:
无需显式引用std::member 即可引用std 命名空间中的成员的能力。例如:
#include <iostream>
using namespace std;
...
cout << "Hi" << endl;
对比
#include <iostream>
...
std::cout << "Hi" << std::endl;
【讨论】:
你绝对不应该说:
using namespace std;
在您的 C++ 标头中,因为这超出了使用命名空间的全部意义(这样做会构成“命名空间污染”)。以下是有关此主题的一些有用资源:
1) Standard convention for using “std” 上的 stackoverflow 线程
2) Herb Sutter 在Migrating to Namespaces 上的一篇文章
3) FAQ 27.5 来自 Marshall Cline 的 C++ Faq lite。
【讨论】:
首先,这在 C 中不是必需的 - C 没有命名空间。在 C++ 中,std 命名空间中的任何内容,包括大部分标准库。如果你不这样做,你必须像这样显式地访问命名空间的成员:
std::cout << "I am accessing stdout" << std::endl;
【讨论】:
首先,在 C 中从不需要 using 指令,因为 C 根本不支持命名空间。
using 指令在 C++ 中从不真正必需,因为命名空间中的任何项目都可以通过在它们前面加上 std:: 来直接访问。所以,例如:
using namespace std;
string myString;
相当于:
std::string myString;
您是否选择使用它是一个偏好问题,但是公开整个std 命名空间以节省一些击键通常被认为是不好的形式。仅公开命名空间中特定项目的另一种方法如下:
using std::string;
string myString;
这允许您仅公开您特别需要的 std 命名空间中的项目,而不会有无意中公开您不打算公开的内容的风险。
【讨论】:
命名空间是一种包装代码的方式,以避免混淆和名称冲突。例如:
文件 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 更快。
【讨论】:
你永远不必声明 using namespace std;使用它是不好的做法,你应该使用 std:: 如果你不想输入 std:: 总是在某些情况下你可以做这样的事情:
using std::cout;
通过使用 std::,您还可以判断程序的哪些部分使用标准库,哪些不使用。更重要的是可能与包含的其他功能发生冲突。
Rgds 莱恩
【讨论】:
std:: 更具可读性,并且比在每个文件的顶部有三十行using std::whatever; 更易于维护。
C++ 标准库中的所有文件都在 std 命名空间中声明其所有实体。
例如:使用 iostream 中定义的cin,cout
替代方案:
using std::cout;
using std::endl;
cout << "Hello" << endl;
std::cout << "Hello" << std::endl;
【讨论】:
没有什么要求你做的——除非你是 C++ 标准库的实现者并且你想在以“新”和“旧”风格声明头文件时避免代码重复:
// cstdio
namespace std
{
// ...
int printf(const char* ...);
// ...
}
.
// stdio.h
#include <cstdio>
using namespace std;
好吧,当然示例有些做作(您同样可以使用普通的<stdio.h> 并将其全部放在<cstdio> 的std 中),但Bjarne Stroustrup 在他的The C++ Programming Language 中显示了这个示例。
【讨论】:
每当您使用在命名空间中声明的内容时都会使用它。 C++ 标准库在命名空间 std 中声明。因此你必须这样做
using namespace std;
除非你想在另一个命名空间中调用函数时指定命名空间,像这样:
std::cout << "cout is declared within the namespace std";
您可以在http://www.cplusplus.com/doc/tutorial/namespaces/ 阅读更多相关信息。
【讨论】: