简体   繁体   English

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

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

I would like to use -1 to indicate a size that has not yet been computed: 我想用-1来表示尚未计算的大小:

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

and I was wondering why isn't there a more expressive way: 而我想知道为什么没有更具表现力的方式:

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

It basically comes down to a fairly simple fact: std::string includes searching capability, and that leads to a requirement for telling the caller that a search failed. 它基本上归结为一个相当简单的事实: std::string包含搜索功能,这导致需要告诉调用者搜索失败。 std::string::npos fulfills that requirement. std::string::npos满足该要求。

std::vector doesn't have any searching capability of its own, so it has no need for telling a caller that a search has failed. std::vector没有自己的搜索功能,因此无需告诉调用者搜索失败。 Therefore, it has no need for an equivalent of std::string::npos . 因此,它不需要等效的std::string::npos

The standard algorithms do include searching, so they do need to be able to tell a caller that a search has failed. 标准算法确实包括搜索,因此他们需要能够告诉呼叫者搜索失败。 They work with iterators, not directly with collections, so they use a special iterator (one that should never be dereferenced) for this purpose. 它们使用迭代器,而不是直接使用集合,因此它们使用一个特殊的迭代器(一个永远不应被解除引用的迭代器)用于此目的。 As it happens, std::vector::end() returns an iterator suitable for the purpose, so that's used--but this is more or less incidental. 碰巧的是, std::vector::end()返回一个适合此目的的迭代器,因此使用了 - 但这或多或少是偶然的。 It would be done without (for example) any direct involvement by std::vector at all. 没有(例如) std::vector任何直接参与都可以完成。

From cppreference : 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是sizeof运算符的结果的无符号整数类型,以及sizeof运算符和alignof运算符(自C ++ 11起)....

...std::size_t can store the maximum size of a theoretically possible object of any type... ... std :: size_t可以存储任何类型的理论上可能的对象的最大大小......

size_t is unsigned, and can't represent -1. size_t是无符号的,不能表示-1。 In reality if you were to attempt to set your sizes to -1, you would actually be setting them to the maximum value representable by a size_t . 实际上,如果您尝试将大小设置为-1,则实际上将它们设置为size_t可表示的最大值。

Therefore you should not use size_t to represent values which include the possible size of a type in addition to a value indicating that no size has been computed, because any value outside the set of possible sizes can not be represented by a size_t . 因此,除了指示未计算大小的值之外,不应使用size_t来表示包含类型的可能大小的值,因为可能大小集之外的任何值都不能由size_t表示。

You should use a different type which is capable of expressing all of the possible values you wish to represent. 您应该使用能够表达您希望表示的所有可能值的其他类型。 Here is one possibility: 这是一种可能性:

struct possibly_computed_size_type
{
    size_t size;
    bool is_computed;
};

Of course, you'll probably want a more expressive solution than this, but the point is that at least possibly_computed_size_type is capable of storing all of the possible values we wish to express. 当然,你可能想要比这更具表现力的解决方案,但关键是至少possibly_computed_size_type能够存储我们希望表达的所有可能的值。

One possibility is to use an optional type. 一种可能性是使用optional类型。 An optional type can represent the range of values of a type, and an additional value meaning 'the object has no value'. optional类型可以表示类型的值范围,附加值表示“对象没有值”。 The boost library provides such a type. boost库提供了这样的类型。

The standard library also provides an optional type as an experimental feature. 标准库还提供可选类型作为实验功能。 Here is an example I created using this type: http://ideone.com/4J0yfe 以下是我使用此类型创建的示例: http//ideone.com/4J0yfe

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM