这个问题可能是一个重复的问题,但我找不到一个好的答案。简而言之,我需要声明什么?
using namespace std;
C++程序中怎么用?
这个问题可能是一个重复的问题,但我找不到一个好的答案。简而言之,我需要声明什么?
using namespace std;
C++程序中怎么用?
自C++标准被接受以来,几乎所有的标准库都在std命名空间内。因此,如果您不想在所有标准库调用前加上std::
,则需要添加using指令。
然而,
using namespace std;
这被认为是一种不好的做法,因为你实际上导入了整个标准命名空间,从而为名称冲突开启了许多可能性。最好只导入你在代码中实际使用的东西,例如
using std::string;
没有什么作用,它是一种简写,避免在该命名空间中的所有内容前缀都加上std::。
std::
的代码上工作,就像我不想使用 using namespace some_tools;
隐式导入任何名称空间一样。 - Potatoswatterusing std::string
。 - Matthieu M.从技术上讲,你可能需要使用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_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)
);
在像这样的代码中,std::
只会造成干扰。
如果在实现文件中使用using namespace std;
,我不认为这是可恶的犯罪行为(但它甚至可以被限制在函数范围内,例如swap示例中)。
绝对不要将using语句放入头文件中。原因是这会为其他可能在问题文件之后被包含的头文件污染命名空间,可能导致其他无法控制的头文件出现错误。(这也增加了惊喜因素:包括文件的人可能没有预料到所有种类的名称都是可见的。)
可以直接引用std
命名空间中的成员,而不需要显式地引用std::member
。例如:
#include <iostream>
using namespace std;
...
cout << "Hi" << endl;
对比。
#include <iostream>
...
std::cout << "Hi" << std::endl;
你绝对不应该说:
using namespace std;
using namespace std;
string myString;
等同于:
std::string myString;
是否选择使用它是个人喜好问题,但为了省几次按键而暴露整个 std
命名空间通常被认为是不好的形式。一种替代方法仅暴露命名空间中特定的项,如下所示:
using std::string;
string myString;
std
命名空间中的项,而不会意外地暴露你不想要的东西。首先,C语言中不需要这样做 - C语言没有命名空间。在C++中,任何位于std
命名空间中的内容都包括大部分标准库。如果您不这样做,您必须显式地访问命名空间的成员,如下所示:
std::cout << "I am accessing stdout" << std::endl;
命名空间是一种包装代码以避免混淆和名称冲突的方法。例如:
文件 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
更快捷。除非你是C++标准库的实现者,并且想要避免在“新”和“旧”风格的头文件中声明代码重复,否则没有任何需要你做的事情:
// cstdio
namespace std
{
// ...
int printf(const char* ...);
// ...
}
.
// stdio.h
#include <cstdio>
using namespace std;
当然,这个例子有些牵强附会(你同样可以使用普通的<stdio.h>
并将其全部放在<cstdio>
中),但Bjarne Stroustrup在他的The C++ Programming Language一书中展示了这个例子。
C++标准库中的所有文件都在std命名空间中声明其所有实体。
例如:要使用iostream中定义的cin,cout
替代方案:
using std::cout;
using std::endl;
cout << "Hello" << endl;
std::cout << "Hello" << std::endl;