为什么C ++ 20中引入了std :: ssize()?

时间:2019-05-20 08:46:28

标签: c++ c++20

C++20引入了std::ssize()免费功能,如下所示:

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

似乎可以使用static_cast来实现,将cl ass C size()成员函数的返回值转换为其已签名的对应值。

由于C的size()成员函数总是返回非负值,所以为什么有人要将它们存储在带符号的变量中?万一真的想要,那只是简单的static_cast问题。

为什么在C ++ 20中引入了std::ssize()

2 个答案:

答案 0 :(得分:53)

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1227r1.html中描述了基本原理。引号:

  

在C ++ 17中采用span时,它使用带符号整数作为索引和大小。部分原因是允许使用“ -1”作为前哨值,以指示其大小在编译时未知的类型。但是让STL容器的size()函数返回带符号的值是有问题的,因此引入了P1089来“修复”问题。它获得了多数支持,但没有获得共识所需的2比1利润。

     

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

答案 1 :(得分:38)

由埃里克·尼布勒(Eric Niebler)感激地stolen

  

'Unsigned types signal that a negative index/size is not sane'原为   最初设计STL时的普遍智慧。但从逻辑上讲   事情不一定是积极的。我可能想保持计数   一个有符号整数,表示添加到或中的元素数   从集合中删除。然后,我想将其与   集合的大小。如果集合的大小是无符号的,现在   我被迫混合使用有符号和无符号算法,这是一个Bug场。   编译器对此有所警告,但是因为STL的设计相当漂亮   迫使程序员陷入这种情况的警告如此普遍   大多数人将其关闭。很遗憾,因为这隐藏了真实的   错误。

     

在接口中使用无符号整数并不是很多人认为的福音   是。如果用户偶然将一个略微负数传递给   API,它突然变成了一个巨大的正数。 API是否采用了   编号,然后可以通过断言   数字大于或等于零。

     

如果我们将对无符号整数的使用限制为可旋转(例如,掩码)   并在其他地方使用带符号的整数,则错误发生的可能性较小,   并且更容易检测它们何时发生。