C ++中“std :: size_t”是否合理?
在我inheritance的一些代码中,我经常使用size_t
和std
命名空间限定符。 例如:
std::size_t n = sizeof( long );
它编译并运行良好,当然。 但对我来说这似乎是不好的做法(也许是从C结束?)。
是不是真的size_t
内置到C ++,因此在全局命名空间? 包含在C ++中使用size_t
所需的头文件?
另一个问这个问题的方法是,下面的程序( 不包括)是否可以在所有C ++编译器上编译?
size_t foo() { return sizeof( long ); }
似乎有关于这个stackoverflow人群混乱
::size_t
是在向后兼容头stddef.h
定义的。 从一开始,它就是ANSI/ISO C
和ISO C++
的一部分。 每个C ++实现必须提供stddef.h
(兼容性)和cstddef
,其中只有后者定义了std::size_t
,而不一定是::size_t
。 参见C ++标准的附录D.
C ++标准第17.4.1.2节第4段指出:
然而,在C ++标准库中,声明和定义(在C中定义为macros的名称除外)在命名空间标准的命名空间范围(3.3.5)内。
这包括在模式cname的标题中find的项目,包括定义size_t的cstddef 。
所以std :: size_t实际上是正确的。
您可以通过包含<stddef.h>
而不是<cstddef>
来在全局名称空间中获取size_t
。 我看不到任何明显的好处,并且该function已被弃用。
size_t没有内置到C ++中。 而且它没有被默认定义。 这个不用GCC编译:
int main(int argc, char** argv) { size_t size; }
也就是说,size_t是POSIX的一部分,如果你只使用基本的东西,比如<cstdlib>
,你最终可能会定义它。
你可以争辩说,std :: size_t是size_t的C ++等价物。 正如Brian所指出的那样,std ::被用作命名空间来避免设置不适合每个人的全局variables。 这就像std :: string,它也可以在根名称空间中定义。
std::size_t n = sizeof( long );
其实,你没有问过上面特别的一个坏习惯。 使用size_t,使用std命名空间进行限定,…
正如C ++标准所说(18.1),size_t是标准头文件中定义的types。 我build议放弃任何关于C语言inheritance的想法和印象。 C ++是一个单独的,不同的语言,最好是这样考虑。 它有自己的标准库,并且C ++标准库的所有元素都是在名称空间std中定义的。 但是,可以在C ++程序中使用C标准库的元素。
我会考虑包括一个肮脏的黑客。 C ++标准规定标题的内容是相同的或基于C标准库的相应标题,但在许多情况下,已经应用了更改。 换句话说,它不是将C头直接复制粘贴到C ++头文件中。
size_t不是C ++中的内置types。 它是一种定义types的types,用于指定sizeof()运算符的返回types,因为sizeof()的实际返回types是实现定义的,所以C ++标准通过定义size_t来统一。
下面的程序(不包括)是否可以在所有C ++编译器上编译?
size_t foo() { return sizeof( long ); }
C ++标准说(1.4):
在库中定义的名称具有命名空间范围(7.3)。 AC ++翻译单元(2.1)通过包含适当的标准库头(16.2)来获得对这些名称的访问。
size_t是在std命名空间中定义的名字,所以在这种情况下,每个使用这个名字的程序都应该包含相应的头文件。
接下来,3.7.3章节说:
但是,引用std,std :: bad_alloc和std :: size_t是格式不正确的,除非通过包含相应的头来声明名称。
鉴于此,使用size_t但不包括头的程序是不合格的。
有时候其他库会定义自己的size_t。 例如boost。 std :: size_t指定你肯定需要c ++标准的。
size_t是一个c ++标准types,它是在名字空间std中定义的。
我认为澄清是足够清楚的。 std::size_t
在C ++和::size_t
很有意义(至less)在C中是有意义的。
然而问题仍然存在。 即是否可以认为::size_t
和std::size_t
是兼容的?
从纯粹的types安全的angular度来看,它们不一定是相同的,除非它被定义在某个地方,它们必须是相同的。
我想很多人正在使用一个拉:
---- // a.hpp #include <string> void Foo( const std::string & name, size_t value ); ----- // a.cpp #include "a.hpp" using namespace std; void Foo( const string & name, size_t value ) { ... }
所以在头文件中你明确地使用::size_t
而在源文件中你将使用std::size_t
。 所以他们必须是兼容的,对吧? 否则,你会得到一个编译器错误。
/ Michael S.
GNU编译器头包含类似的东西
typedef long int __PTRDIFF_TYPE__; typedef unsigned long int __SIZE_TYPE__;
然后stddef.h constains类似
typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t;
最后cstddef文件包含类似的东西
#include <stddef.h> namespace std { 使用:: ptrdiff_t; 使用:: size_t; }
我觉得应该说清楚。 只要包含<cstddef>,就可以使用size_t或std :: size_t,因为size_t是在std名称空间之外的typedefed,然后被包含。 实际上你有
typedef long int ptrdiff_t; typedef unsigned long int size_t; namespace std { 使用:: ptrdiff_t; 使用:: size_t; }