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

Mar*_*dik 4 c++ containers c++-standard-library

我想用-1来表示尚未计算的大小:

std::vector<std::size_t> sizes(nResults, -1);
Run Code Online (Sandbox Code Playgroud)

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

std::vector<std::size_t> sizes(nResults, std::vector<std::size_t>::npos);
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 6

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

std::vector它没有自己的搜索功能,因此无需告诉调用者搜索失败.因此,它不需要相当于std::string::npos.

标准算法确实包括搜索,因此他们需要能够告诉呼叫者搜索失败.它们使用迭代器,而不是直接使用集合,因此它们使用一个特殊的迭代器(一个永远不应被解除引用的迭代器)用于此目的.碰巧的是,std::vector::end()返回一个适合此目的的迭代器,以便使用 - 但这或多或少是偶然的.没有(例如)任何直接参与都可以完成std::vector.


Bri*_*ice 2

来自cppreference

std::size_t 是 sizeof 运算符以及 sizeof 运算符和alignof 运算符结果的无符号整数类型 (C++11 起)....

...std::size_t 可以存储理论上可能的任何类型对象的最大大小...

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

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

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

struct possibly_computed_size_type
{
    size_t size;
    bool is_computed;
};
Run Code Online (Sandbox Code Playgroud)

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

一种可能性是使用optional类型。类型optional可以表示类型的值范围,附加值表示“该对象没有值”。 boost库提供了这样的类型。

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

  • -1。请注意,std::string::npos 被定义为“((std::size_t)(-1))”,因此存在现有技术。您建议不要将单个值指定为“特殊值”(这是完全合理的),而是浪费额外的字节! (4认同)