对象、引用、函数(包括函数模板特化)和表达式具有称为类型的性质,它限制了对这些实体所容许的操作,并给原本寻常的位序列提供了语义含义。
附加性基本类型及宏
sizeof 运算符返回的无符号整数类型
std::size_t
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
定义于头文件 | ||
typedef /*implementation-defined*/ size_t; |
std::size_t 是 sizeof 运算符还有 sizeof... 运算符和 alignof 运算符 (C++11 起)所返回的一种无符号整数类型。
注意
size_t 可以存放下理论上可能存在的对象的最大大小,该对象可以是任何类型,包括数组。大小无法以 std::size_t
表示的类型是病式的。 (C++14 起)在许多平台上(使用分段寻址的系统除外),std::size_t 可以存放下任何非成员的指针,此时可以视作其与 std::uintptr_t 同义。
std::size_t 通常被用于数组索引和循环计数。使用其它类型来进行数组索引操作的程序可能会在某些情况下出错,例如在 64 位系统中使用 unsigned int 进行索引时,如果索引号超过 UINT_MAX 或者依赖于 32 位取模运算的话,程序就会出错。
在对诸如 std::string、std::vector 等 C++ 容器进行索引操作时,正确的类型是该容器的成员 typedef size_type,而该类型通常被定义为与 std::size_t 相同。
调用示例
#include <cstddef>
#include <iostream>
int main()
{
const std::size_t N = 10;
int* a = new int[N];
for (std::size_t n = 0; n < N; ++n)
{
a[n] = n;
}
for (std::size_t n = N; n-- > 0;) // 对于无符号类型的逆向循环技巧。
{
std::cout << a[n] << " ";
}
delete[] a;
return 0;
}
输出
在两个指针相减时返回的有符号整数类型
std::ptrdiff_t
定义于头文件 | ||
typedef /*implementation-defined*/ ptrdiff_t; |
std::ptrdiff_t
是二个指针相减结果的有符号整数类型。
注意
std::ptrdiff_t
被用于指针算术及数组下标,若负值可行。使用其他类型,如 int 的程序,可能诸如 64 位的系统上失败,在当下标超过 INT_MAX 或依赖 32 位模算术时。
在用 C++ 容器库工作时,迭代器的差的准确类型是成员 typedef difference_type ,它常与 std::ptrdiff_t
相同。
只有指向同一数组元素的指针(含指向数组结尾后一位置的指针)可以相减。
若数组过大(大于 PTRDIFF_MAX 个元素,而小于 SIZE_MAX 字节),则二个指针的差可能无法以 std::ptrdiff_t
表示,二个这种指针相减的结果是未定义的。
对于短于 PTRDIFF_MAX 的 char 数组, std::ptrdiff_t
表现为 std::size_t 的有符号对应物:它可以存储数组的大小,而且在多数平台上等同于 std::intptr_t 。
调用示例
#include <cstddef>
#include <iostream>
#include <iomanip>
int main()
{
const std::size_t N = 100;
int* a = new int[N];
int* end = a + N;
for (std::ptrdiff_t i = N; i > 0; --i)
{
if (i % 10 == 0)
{
std::cout << std::endl;
}
std::cout << std::setw(3) << (*(end - i) = i) << ' ';
}
std::cout << std::endl;
delete[] a;
return 0;
}
输出
空指针字面量 nullptr 的类型
std::nullptr_t
定义于头文件 | ||
typedef decltype(nullptr) nullptr_t; | (C++11 起) |
std::nullptr_t 是空指针字面量 nullptr 的类型。它是既非指针类型亦非指向成员指针类型的独立类型。
示例
若二个重载接受不同指针类型,则需要 std::nullptr_t 的重载以接受空指针常量。
调用示例
#include <cstddef>
#include <iostream>
void f(int* pi)
{
std::cout << "Pointer to integer overload" << std::endl;
}
void f(double* pd)
{
std::cout << "Pointer to double overload" << std::endl;
}
void f(std::nullptr_t nullp)
{
std::cout << "null pointer overload" << std::endl;
}
int main()
{
int* pi;
double* pd;
f(pi);
f(pd);
f(nullptr); // 无 void f(nullptr_t) 可能有歧义
// f(0); // 歧义调用:三个函数全部为候选
// f(NULL); // 若 NULL 是整数空指针常量则为歧义
// (如在大部分实现中的情况)
return 0;
}