尺寸 t - "std::size_t"在C++有意义吗?
size t - Does "std::size_t" make sense in C++?
在我继承的一些代码中,我看到size_t
经常使用带有std
命名空间限定符。 例如:
std::size_t n = sizeof( long );
当然,它可以编译和运行良好。 但这对我来说似乎是不好的做法(也许是从 C 继承下来的?
size_t
不是内置在C++中,因此内置在全局命名空间中,这不是真的吗? 是否需要包含头文件才能在C++中使用size_t
?
问这个问题的另一种方法是,下面的程序(没有包含)是否应该在所有C++编译器上编译?
size_t foo()
{
return sizeof( long );
}
堆栈溢出人群中似乎对此感到困惑
::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 中定义为宏的名称)在命名空间 std 的命名空间范围 (3.3.5) 内。
这包括在模式 cname 的标头中找到的项目,包括定义size_t的 cstddef。
所以std::size_t实际上是正确的。
,您可以通过包含 <stddef.h>
而不是 <cstddef>
来获取全局命名空间中的size_t
。 我看不到任何明显的好处,并且该功能已弃用。
内置到C++中。默认情况下没有定义它。这个不能用 GCC 编译:
int main(int argc, char** argv) {
size_t size;
}
也就是说,size_t是 POSIX 的一部分,如果您只使用像 <cstdlib>
这样的基本东西,您最终可能会定义它。
你可以争辩说std::size_t C++等同于size_t。正如 Brian 指出的那样,std:: 被用作命名空间,以避免设置不适合所有人的全局变量。它就像 std::string,也可以在根命名空间中定义。
std::size_t n = sizeof( long );
实际上,您还没有问过上述具体似乎是不好的做法。使用size_t,使用标准命名空间进行限定,...
正如C++标准(18.1)所说,size_t是标准标头中定义的类型。我建议放弃任何关于可能从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但不包含标头的程序格式不正确。
有时其他库会定义自己的size_t。 例如提升。 std::size_t 指定您绝对需要 C++ 标准版。
size_t 是 C++ 标准类型,它在命名空间 std 中定义。
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命名空间标准 { 使用 ::p trdiff_t; 使用 ::size_t;}
我认为这应该说明问题。只要包含
typedef long int ptrdiff_t;typedef unsigned long int size_t;命名空间标准 { 使用 ::p trdiff_t; 使用 ::size_t;}
我认为澄清已经足够清楚了。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
.所以它们一定是兼容的,对吧?否则,将出现编译器错误。
/迈克尔·
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 从头开始为应用程序创建 docker 映像是否有意义?
- 在c++中,如果首先禁止默认构造,那么禁止复制构造有意义吗
- sizeof(函数)有意义吗?
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 插入向量时,使用lambda的返回而不是函数的返回是否有意义?
- 在 C++17 中使用 const std::string& 参数有意义吗?
- 基础类模板参数的有意义名称
- 内联这个函数,确实有意义
- 将 final 关键字添加到没有基类(未派生)的类中的虚函数是否有意义
- 左移负整数为零是否有意义?
- 是否有一个上下文表达式`a.b :: c`有意义
- 是否有一些有意义的统计数据来证明保持有符号整数算术溢出未定义是合理的
- 将可选与reference_wrapper相结合是否有意义?
- 函数返回rvalue参考是否有意义
- 将 [[noreturn]] 添加到主函数是否有意义
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?
- YAML-CPP 节点诊断有意义的错误
- 拥有一个没有构造函数的类是否有意义