我一直认为我们应该在包含后使用命名空间,例如,我们应该使用:
#include <vector>
using std::vector;
而不是
using std::vector;
#include <vector>
但我发现第二个是好的,让我困惑的是它们的不同排序会导致不同的结果。参见下面的简单示例:这里有两个头文件和一个c ++文件。
// test1.h
#include <vector>
using std::vector;
#include "test2.h"
// test2.h
vector<int> v;
// test.cpp
#include "test1.h"
int main()
{
return 0;
}
尽管test2.h不包含vector,但它编译好以上所有。 奇怪的是当我交换使用std :: vector的顺序时;和#include一样,会发生这样的编译错误:
错误C2143:语法错误:缺少';'在'&lt;'
之前错误C2501:'vector':缺少存储类或类型说明符
错误C2143:语法错误:缺少';'在'&lt;'
之前错误C2874:using-declaration导致'vector'的多重声明
我不了解内部,命名空间的顺序和包含真的很重要吗?为什么这样呢?
答案 0 :(得分:1)
将名称转储到全局命名空间通常是一个坏主意,它们可能会与用户声明的名称冲突 - 特别是在标题中,您强制污染该标题的所有用户。话虽如此:
我发现第二个是好的
仅因为某些内容已包含<vector>
或已声明为std::vector
。正如您在后面的示例中所看到的,否则会出现错误。
我不了解内部,命名空间的顺序和包含真的很重要吗?
是的,using声明只能引用已声明的名称。
为什么这样呢?
因为这就是语言的运作方式。您通常不能使用尚未声明的名称。
答案 1 :(得分:1)
// test2.h
vector<int> v;
头文件应该是自给自足的。像这样编写test2.h要求用户同时#include <vector>
并添加using
声明,以便可以在不限定其名称的情况下编写vector
。这意味着标题不是自给自足的,因为你不能简单地#include
它而不先做其他事情。
您也不应该在头文件中定义变量。在头文件中,您应该只声明extern
个变量。
#ifndef TEST2_H
#define TEST2_H
#include <vector>
extern std::vector<int> v;
#endif
这里我还添加了#ifndef / #define guard,因此可以多次包含头文件而不会出错。我还使用了完全限定的std::vector
而没有使用using
:将using
声明放在头文件中是合法的,但不好的做法。
答案 2 :(得分:1)
此:
using std::vector;
#include <vector>
不确定,除非该文件已包含 <vector>
。
重要的是,#include
执行文字替换。它就像在#include
指令上粘贴包含文件的内容一样。头文件不是自己编译的,只是形成正在编译的源文件的文本部分。
因此,您的示例有效,因为在包含test2.h
时,正在编译的源文件(test.cpp
)已包含来自#include <vector>
的{{1}}和using std::vector;
。这就是为什么当你交换时它会中断的原因 - test1.h
在test2.h
声明之前被包含在内,因此在使用它时不存在不合格的using
。
答案 3 :(得分:0)
预处理程序指令#include
是文本替换操作。它将读取包含的文件并将#include
替换为其内容。如果您根据操作的内容进行考虑,答案应该是明确的。
预处理后main.cpp
变为:
// start test1.h
#include <vector>
using std::vector;
// start test2.h
vector<int> v;
// end test2.h
// end test1.h
int main()
{
return 0;
}
如果您更改using
指令的顺序以包含标题,您将获得(删除评论):
#include <vector>
vector<int> v;
using std::vector;
//...
在v
的定义时,尚未看到using声明,编译器不知道vector
的含义,因此也不知道错误消息。
现在回到最初的假设:
using std::vector;
#include <vector>
但我发现第二个是好的
不,不行。根据您拥有的其他包含内容,它可能会编译,但在编译器看到声明的元素之前,您无法提供using声明。如果上面的两行编译,则意味着在第一行之前的某处,包含的扩展已经将std::vector
的声明带入此翻译单元。尝试在单个.cpp中单独编译它,你会看到一些错误。