Why is std::ssize() introduced in C++20?

C++20 introduced the std::ssize() free function as below:

template <class C>
constexpr auto ssize(const C& c)
-> std::common_type_t<std::ptrdiff_t,
std::make_signed_t<decltype(c.size())>>;

A possible implementation seems using static_cast, to convert the return value of the size() member function of class C into its signed counterpart.

Since the size() member function of C always returns non-negative values, why would anyone want to store them in signed variables? In case one really wants to, it is a matter of simple static_cast.

Why is std::ssize() introduced in C++20?

10982 次浏览

基本原理在 这张纸中有描述,引用如下:

当 span 被采用到 C + + 17中时,它使用一个有符号整数作为索引和大小。这在一定程度上是为了允许使用“ -1”作为前哨值来指示在编译时其大小未知的类型。但是,如果 STL 容器的 size ()函数返回一个带符号的值,那么就会出现问题,因此引入 P1089来“修复”这个问题。它获得了大多数人的支持,但没有达成共识所需的2比1的优势。

本文 P1227提出了添加非成员 std: : ssize 和成员 ssize ()函数的建议。包含这些内容将使某些代码更加直观,并允许在大小计算中避免不必要的无符号性。其想法是,如果 ssize ()通过 std: : ssize ()和作为成员函数可用于所有容器,则对 P1089的阻力将会降低。

来自 Eric Niebler 的无偿 被偷了:

'Unsigned types signal that a negative index/size is not sane' was 当 STL 最初被设计的时候,流行的智慧。但是从逻辑上来说, 一些事情不需要是积极的。我可能想要保持一个计数在 a signed integer to denote the number of elements either added to or 从集合中移除。然后我想将它与 集合的大小。如果集合的大小是无符号的,现在 我被迫混合使用有符号和无符号算术,这是一个错误农场。 编译器对此提出警告,但是因为 STL 的设计很漂亮 迫使程序员进入这种情况,这种警告是很常见的 大多数人都会把它关掉,真可惜,因为它隐藏了真实的一面 虫子。

Use of unsigned ints in interfaces isn't the boon many people think it 如果用户不小心将一个略负的数字传递给 API, it suddenly becomes a huge positive number. Had the API taken the 号,然后它可以通过断言 number is greater than or equal to zero.

如果我们将无符号整型的使用限制为位操作(例如,掩码) 并且在其他地方使用带符号整型,bug 就不太可能发生, and easier to detect when they do occur.