C++ c+中的名称空间问题+;11?

C++ c+中的名称空间问题+;11?,c++,gcc,c++11,glibc,C++,Gcc,C++11,Glibc,有人能解释一下吗 $ cat test.cpp #include <string> std::string div; $ g++ -c test.cpp $ g++ -std=c++11 -c test.cpp test.cpp:2:13: error: 'std::string div' redeclared as different kind of symbol In file included from /usr/include/c++/4.7.1/cstdlib:66:

有人能解释一下吗

$ cat test.cpp 
#include <string>
std::string div;
$ g++ -c test.cpp 
$ g++ -std=c++11 -c test.cpp 
test.cpp:2:13: error: 'std::string div' redeclared as different kind of symbol
In file included from /usr/include/c++/4.7.1/cstdlib:66:0,
                 from /usr/include/c++/4.7.1/ext/string_conversions.h:37,
                 from /usr/include/c++/4.7.1/bits/basic_string.h:2814,
                 from /usr/include/c++/4.7.1/string:54,
                 from test.cpp:1:
/usr/include/stdlib.h:787:14: error: previous declaration of 'div_t div(int, int)'
$
$cat test.cpp
#包括
std::字符串div;
$g++-c test.cpp
$g++-std=c++11-c test.cpp
test.cpp:2:13:错误:“std::string div”重新声明为不同类型的符号
在/usr/include/c++/4.7.1/cstdlib:66:0中包含的文件中,
从/usr/include/c++/4.7.1/ext/string_conversions.h:37,
从/usr/include/c++/4.7.1/bits/basic_string.h:2814,
从/usr/include/c++/4.7.1/string:54,
来自测试。cpp:1:
/usr/include/stdlib.h:787:14:错误:先前的“div_t div(int,int)”声明
$

对于C++11模式,
div
符号不应该也在
std
命名空间中吗?或者它是我的系统特有的吗?

div
中的一个函数

在C++11中,允许
头在全局名称空间中放置内容

C++11§17.6.1.2/4
“除非第18条至第30条和附件D中另有说明,否则每个标题
cname
的内容应相同 与C标准库(1.2)或C Unicode TR(视情况而定)中规定的相应标题
name.h
,如同通过包含一样。但是,在C++标准库中 在C)中定义为宏的名称位于命名空间
std
的命名空间范围(3.3.6)内 未指定这些名称是否首先在全局命名空间范围内声明,然后注入 通过显式使用声明(7.3.3)导入命名空间std。”

反映了常用C++实现的真实性。 所以,除了形式上的改变,实际上什么都没有改变:您看到的行为现在被标准认可,而不是一个必须考虑的实现工件

此外,形式上的改变使争论更容易,因此最好包括
.h
标题,而不是
c
xxx标题

/usr/include/stdlib.h

.h
C stdlib头中的每个名称都驻留在全局名称空间中(显然)

<> P>另外,任何<代码> Cudier- STD< /Cord>命名空间中定义“代码>标题”的H./Cube >相应的名称,但也允许在全局命名空间中拥有它们(因此它们可以做< /P>)。
// cHEADER
#include <HEADER.h>

namespace std{
using ::one_name_from_HEADER;
using ::another_name_from_HEADER;
// and so on...
}
),这使得这些标题之间的整体区别相当。。。真的没用。

17.6.4.3.3/1规定:

在头中声明为具有外部链接的对象的每个名称都保留给实现,以在命名空间
std
和全局命名空间中指定具有外部链接的库对象


div
是在头cstdlib中声明为具有外部链接的函数的名称,因此是全局命名空间中的保留名称。不允许使用此名称。

我发现编译器经常违反规则,即c标准库标题的
c*
对应者定义的所有内容都必须位于
std
命名空间中。显然
string
包含
cstdlib
,这违反了规则,并将
div
放在全局命名空间中。有趣的是,在我指定c++11模式之前,它工作正常。我不能100%确定它是否是一个编译器错误:clang做了完全相同的事情…@SethCarnegie-库实现经常违反该规则的原因是没有这样的规则。在C++03中有,但这是一厢情愿的想法;这无法完成,并且该规则已被C++11删除。是否有任何标准方法可以防止这种冲突,而不必在每次使用时都限定我的div变量?@PeteBecker,这令人失望。我知道C++11允许这样做,但我希望实现不要这样做。我从未意识到C++03实际上不允许C头污染全局名称空间,而且实现根本不符合规范;您得到的保证是
#include
将一组名称放入全局命名空间,而
#include
将一组名称放入命名空间
std
。使用cheader的另一个好理由是避免使用宏。例如,<代码> <代码>通常不允许从代码> >代码>()中查看所有宏。@杰西古德:你知道VisualC++(你的引用)是否符合这方面的标准?@阿尔夫,AfAIK,它是标准一致的。libstdc++也做同样的事情。C标准规定,
头中声明的任何函数都可以额外实现为类似宏的函数
。在C++中,只有C定义为宏的代码>在C++标准库中定义为宏,因为C标准称可能附加地实现,在C++中没有限制宏的限制。
// HEADER.h
#include <cHEADER>

using std::one_name_from_HEADER;
using std::another_name_from_HEADER;
// and so on...
}