为什么我们有 std::string::npos 而没有 std::vector::npos?

Why do we have std::string::npos but no std::vector::npos?

我想用-1来表示一个尚未计算的尺寸:

std::vector<std::size_t> sizes(nResults, -1);

我想知道为什么没有更具表现力的方式:

std::vector<std::size_t> sizes(nResults, std::vector<std::size_t>::npos);

来自cppreference

std::size_t is the unsigned integer type of the result of the sizeof operator as well as the sizeof operator and the alignof operator (since C++11)....

...std::size_t can store the maximum size of a theoretically possible object of any type...

size_t 是无符号的,不能代表-1。实际上,如果您尝试将大小设置为 -1,您实际上会将它们设置为 size_t 可表示的最大值。

因此,您不应该使用 size_t 来表示除了指示未计算大小的值之外还包括类型的可能大小的值,因为可能大小集之外的任何值都不能由 size_t.

表示

您应该使用能够表达您希望表示的所有可能值的不同类型。这是一种可能性:

struct possibly_computed_size_type
{
    size_t size;
    bool is_computed;
};

当然,您可能想要比这更具表现力的解决方案,但关键是至少 possibly_computed_size_type 能够存储我们希望表达的所有可能值。

一种可能性是使用 optional 类型。一个optional类型可以表示一个类型的取值范围,另外一个值表示'the object has no value'。 The boost library provides such a type.

标准库还提供了一个可选类型作为实验性功能。这是我使用此类型创建的示例: http://ideone.com/4J0yfe

它基本上归结为一个相当简单的事实:std::string 包括搜索功能,这导致需要告诉调用者搜索失败。 std::string::npos 满足该要求。

std::vector 本身没有任何搜索功能,因此不需要告诉调用者搜索失败。因此,它不需要等价于 std::string::npos.

标准算法确实包括搜索,因此它们确实需要能够告诉调用者搜索失败。他们使用迭代器,而不是直接使用集合,因此他们为此使用了一个特殊的迭代器(一个永远不应该取消引用的迭代器)。碰巧的是,std::vector::end() returns 一个适合该目的的迭代器,所以它被使用了——但这或多或少是偶然的。 std::vector 完全没有(例如)任何直接参与。