C++标准模板(STL)- 类型支持 (std::size_t,std::ptrdiff_t,std::nullptr_t)

对象、引用、函数(包括函数模板特化)和表达式具有称为类型的性质,它限制了对这些实体所容许的操作,并给原本寻常的位序列提供了语义含义。


附加性基本类型及宏

sizeof 运算符返回的无符号整数类型

std::size_t

定义于头文件 <cstddef>

定义于头文件 <cstdio>

定义于头文件 <cstdlib>

定义于头文件 <cstring>

定义于头文件 <ctime>

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

定义于头文件 <cstddef>

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

定义于头文件 <cstddef>

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;
}

输出

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/133429980
今日推荐