C ++ 20引入了std::ssize()free函数,如下所示:
template <class C>
constexpr auto ssize(const C& c)
-> std::common_type_t<std::ptrdiff_t,
std::make_signed_t<decltype(c.size())>>;
Run Code Online (Sandbox Code Playgroud)
似乎可以使用实现static_cast,将size()cl ass C的成员函数的返回值转换为其已签名的对应函数。
由于size()C 的成员函数始终返回非负值,为什么有人会将它们存储在带符号的变量中?万一真的要,那很简单static_cast。
为什么std::ssize()在C ++ 20中引入?
Nad*_*'El 65
本文描述了基本原理。引用:
当C ++ 17中采用span时,它使用带符号整数作为索引和大小。部分原因是允许使用“ -1”作为前哨值,以指示其大小在编译时未知的类型。但是让STL容器的size()函数返回带符号的值是有问题的,因此引入了P1089来“修复”问题。它获得了多数支持,但没有获得共识所需的2比1利润。
本文P1227是一项建议,以添加非成员std :: ssize和成员ssize()函数。包含这些内容将使某些代码更加简单明了,并可以避免在大小计算中出现不必要的无符号性。这个想法是,如果通过std :: ssize()和作为成员函数使ssize()可用于所有容器,则对P1089的抵抗力将降低。
sp2*_*nny 42
无偿被盗埃里克Niebler:
'Unsigned types signal that a negative index/size is not sane'最初设计STL时,这是流行的智慧。但是从逻辑上讲,事情的数量不一定是肯定的。我可能希望将计数保持为有符号整数,以表示添加到集合中或从集合中删除的元素的数量。然后,我想将其与集合的大小结合起来。如果集合的大小是无符号的,那么现在我不得不混合使用有符号和无符号算术,这是一个Bug场。编译器对此发出警告,但是由于STL的设计几乎迫使程序员陷入这种情况,因此警告非常普遍,以至于大多数人都将其关闭。真可惜,因为这掩盖了真正的错误。在接口中使用unsigned int并不是很多人认为的福音。如果用户偶然将一个略微负数传递给API,则它突然变成一个巨大的正数。如果API将数字作为签名,则可以通过断言该数字大于或等于零来检测情况。
如果我们将无符号整数的使用限制为可旋转(例如掩码),并在其他地方使用带符号的整数,则错误发生的可能性较小,并且更容易检测到它们何时发生。