【发布时间】:2012-09-24 23:49:49
【问题描述】:
当我遇到这个“问题”时,我正在使用 ptrdiff_t 并阅读 C++11 标准。一、事实:
ptrdiff_t 类型(只是一个示例)从标准 C 库头 <stddef.h> 中提取到 <cstddef>(第 18.2/2 节)。第 17.6.1.2 节告诉我们,从 C 标准库中提取的声明将位于 std 命名空间内:
然而,在 C++ 标准库中,声明(在 C 中定义为宏的名称除外)在命名空间
std的命名空间范围 (3.3.6) 内。它是 未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式 using-declarations (7.3.3) 注入命名空间std。
正如它所说,声明可能首先在全局命名空间中声明,然后注入std。因此,对于我的实现来说,以下编译得很好:
#include <cstddef>
int main(int argc, const char* argv[])
{
std::ptrdiff_t x;
ptrdiff_t y;
return 0;
}
我的实现(gcc 4.6.3)必须在全局命名空间中声明ptrdiff_t,然后将其注入std。但是,如果我编译以下代码,我会收到一个错误(注意 <iostream> 包含):
#include <iostream>
int main(int argc, const char* argv[])
{
std::ptrdiff_t x;
ptrdiff_t y;
return 0;
}
main.cpp:在函数“int main(int, const char**)”中:
main.cpp:6:3:错误:“ptrdiff_t”未在此范围内声明
main.cpp:6:3:注意:建议的替代方案:
/usr/include/c++/4.6/i686-linux-gnu/./bits/c++config.h:156:28:注意:'std::ptrdiff_t'
因此,由于std::ptrdiff_t 可用,<iostream> 必须以某种方式包含<cstddef>(尽管不是必需的)。但是为什么全球版本不可用
以前是?即使它实际上是相同的标头,我是否不能期望这种注入是一致的?这似乎是奇怪的行为。是否发生注入可能未指定,但至少应该是一种方式或另一种方式,而不是两者,对吧?
【问题讨论】:
-
未指定表示未指定。谁说没有在命名空间
std中直接声明所有typedef 的标头,那么cstdlib既包括stdlib.h又包括标头? (大概在这种情况下,cstddef包含stddef.h以避免错误地使用全局命名空间中的类型来破坏代码,而iostream仅包含上述标头而不是cstddef以避免污染全局命名空间。) -
为什么不只包括 cstddef?
-
@ildjarn 也许吧。我认为您的想法不符合
cstddef必须在std中声明或全局声明并注入std的要求。在您的示例中,所有内容都将在两个命名空间中单独声明。我可能太接近标准的具体程度了。 -
@asd 当然,我通常会这样做。这只是我遇到的我想知道的事情。
-
@sftrabbit :你在哪里看到这个要求?除了“声明在命名空间
std的命名空间范围内”之外,该标准没有说明任何具体内容。同样,未指定使用什么机制来实现这一点。
标签: c++ c++11 standards header-files c++-standard-library