“std::size_t”在 C++ 中有意义吗?
Posted
技术标签:
【中文标题】“std::size_t”在 C++ 中有意义吗?【英文标题】:Does "std::size_t" make sense in C++? 【发布时间】:2008-10-26 01:55:05 【问题描述】:在我继承的一些代码中,我看到size_t
经常与std
命名空间限定符一起使用。例如:
std::size_t n = sizeof( long );
当然,它编译并运行良好。但这对我来说似乎是一种不好的做法(可能是从 C 继承而来的?)。
size_t
不是内置在 C++ 中并因此位于全局命名空间中吗?在 C++ 中使用 size_t
是否需要包含头文件?
问这个问题的另一种方法是,以下程序(包含 no)是否应该在所有 C++ 编译器上编译?
size_t foo()
return sizeof( long );
【问题讨论】:
C 没有命名空间。 它内置在 C++ 中,当你#include*** 人群似乎对此感到困惑
::size_t
在向后兼容标头 stddef.h
中定义。它从一开始就是ANSI/ISO C
和ISO C++
的一部分。每个 C++ 实现都必须附带 stddef.h
(兼容性)和 cstddef
,其中只有后者定义 std::size_t
而不一定是 ::size_t
。请参阅 C++ 标准的附录 D。
【讨论】:
这里绝对是最好的答案。它基于标准而不是特定的编译器。它回答了最初的问题而没有偏离正线。 另一个不使用using namespace std
的理由
@Darryl:公平地说,所有较旧的答案也是如此。
C++11 标准规定 cstddef 应该定义 stddef.h 所做的一切,包括 ::size_t。所以我认为没有理由使用 std::size_t 代替 size_t。请参阅“18.2.2: 内容与标准 C 库头文件 C++ 标准第 17.4.1.2 节第 4 段指出:
“但是,在 C++ 标准库中,声明和定义(在 C 中定义为宏的名称除外)在命名空间 std 的命名空间范围 (3.3.5) 内。”
这包括在模式 cname 的标题中找到的项目,包括定义 size_t 的 cstddef。
所以 std::size_t 实际上是正确的。
【讨论】:
【参考方案3】:您可以在全局命名空间中获得size_t
,例如,包括<stddef.h>
而不是<cstddef>
。我看不到任何明显的好处,并且该功能已被弃用。
【讨论】:
对否决票的一些解释是礼貌的。答案正确且符合主题。 我不知道是谁投了你的票。您的观察与原始问题非常吻合。 我对你投了反对票,主要是因为有一种不被弃用的方法:使用声明,即using std::size_t
,你没有提到这是一个更好的选择。 :-)
除了我认为@fizzer 是在解释你如何可能在你的 C++ 程序的全局命名空间中使用 size_t,而不是建议你做 i> 所以。
你没有真正回答这个问题。您回答了一个相关问题。【参考方案4】:
size_t 没有内置在 C++ 中。并且默认情况下没有定义。这个不能用 GCC 编译:
int main(int argc, char** argv)
size_t size;
也就是说,size_t 是 POSIX 的一部分,如果您只使用 <cstdlib>
之类的基本内容,您最终可能会定义它。
您可以争辩说 std::size_t 是 size_t 的 C++ 等价物。正如布赖恩所指出的,std:: 被用作命名空间以避免设置不适合所有人的全局变量。它就像 std::string 一样,也可以在根命名空间中定义。
【讨论】:
【参考方案5】:std::size_t n = sizeof( long );
实际上,您还没有问过上面的具体做法是什么。使用 size_t,使用 std 命名空间进行限定,...
正如 C++ 标准 (18.1) 所说, size_t 是在标准 header 中定义的类型。我建议放弃关于可能从 C 语言继承的任何想法和印象。 C++ 是一种独立且不同的语言,最好这样考虑。它有自己的标准库,并且 C++ 标准库的所有元素都在命名空间 std 中定义。但是,可以在 C++ 程序中使用 C 标准库的元素。
我会考虑将其作为一个肮脏的黑客。 C++ 标准规定标头的内容是相同的或基于 C 标准库中的相应标头,但在许多情况下,已应用了更改。换句话说,它不是将 C 头文件直接复制并粘贴到 C++ 头文件中。
size_t 不是 C++ 中的内置类型。它是一种定义类型,用于指定使用哪种整数类型作为 sizeof() 运算符的返回类型,因为 sizeof() 的实际返回类型是实现定义的,所以 C++ 标准通过定义 size_t 来统一。
下面的程序(没有 包括)预计编译 所有 C++ 编译器?
size_t foo() return sizeof( long );
C++ 标准说 (1.4):
库中定义的名称具有命名空间范围 (7.3)。 C++ 翻译单元 (2.1) 通过包含适当的标准库头文件 (16.2) 来获得对这些名称的访问权。
size_t 是在 std 命名空间中定义的名称,因此在这种情况下,每个使用此名称的程序都应包含相应的标头。
接下来,3.7.3章节说:
但是,除非通过包含适当的标头来声明名称,否则引用 std、std::bad_alloc 和 std::size_t 是不正确的。
鉴于此,使用 size_t 但不包含标头的程序格式不正确。
【讨论】:
【参考方案6】:有时其他库会定义自己的 size_t。例如升压。 std::size_t 指定您肯定想要 c++ 标准。
size_t 是一个 c++ 标准类型,它在命名空间 std 中定义。
【讨论】:
这是有道理的。你知道“::size_t”或“std::size_t”(或两者兼有)是语言规范的一部分吗?【参考方案7】:GNU 编译器头文件包含类似
typedef long int __PTRDIFF_TYPE__; typedef unsigned long int __SIZE_TYPE__;
然后 stddef.h 包含类似的东西
typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t;
最后,cstddef 文件包含类似
#include我认为这应该说清楚。只要您包含
typedef long int ptrdiff_t; typedef unsigned long int size_t; 命名空间标准 使用 ::ptrdiff_t; 使用 ::size_t;
【讨论】:
所以 GNU 是这样定义的,这是否意味着所有编译器都这样做?标准是否规定必须如此?【参考方案8】:我认为澄清已经足够清楚了。 std::size_t
在 C++ 中很有意义,::size_t
在 C 中(至少)很有意义。
但是还有一个问题。即假设::size_t
和std::size_t
兼容是否安全?
从纯粹的类型安全的角度来看,它们不一定相同,除非在某处定义它们必须相同。
我认为很多人都在使用一些东西:
----
// 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
。所以他们一定是兼容的,对吧?否则你会得到一个编译器错误。
/迈克尔·S.
【讨论】:
::size_t 在没有命名空间的 C 中没有意义。以上是关于“std::size_t”在 C++ 中有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章