std::ranges::size 应该是 return 一个无符号整数吗?

Is std::ranges::size supposed to return an unsigned integer?

Here 写成 std::ranges::size 应该 return 一个无符号整数。但是,当我在 Eigen 向量(使用 Eigen 3.4)上使用它时,编译如下:

Eigen::VectorXd x;
static_assert(std::same_as<Eigen::VectorXd::Index,
                           decltype(std::ranges::size(x))>);

其中 Eigen::VectorXd::Index 是众所周知的有符号整数。通过查看 std::ranges::size 的实现,我注意到 return 类型是从 x.size() 的 return 类型推断出来的,恰恰是 Eigen::VectorXd::Index。这是 std::ranges::size 的错误吗?或者这是预期的?


2021 年 12 月 27 日更新

上面链接的 C++ 参考页最终更改了 std::ranges::size 函数的描述:它只是 return 一个 整数 ,不一定是无符号的一个!

Is this a bug of std::ranges::size?

没有。 cppreference 文档具有误导性。 std::ranges::size 到 return 不需要无符号整数。在这种情况下,returns 正是 Eigen::VectorXd::size returns.

对于模型 ranges::sized_range 的范围,那将是一个无符号整数,但 Eigen::VectorXd 显然不对这样的范围建模。

But then what is the purpose of std::ranges::ssize compared to std::ranges::size?

std::ranges::ssize 的目的是成为一种获取有符号值的通用方法,无论 std::ranges::size return 是否有符号。在 std::ranges::size return 是有符号类型的情况下,它们之间没有区别。

Is there a reference to back up what you state?

是的。参见 C++ 标准:

[range.prim.size]

Otherwise, if disable_­sized_­range<remove_­cv_­t<T>> ([range.sized]) is false and auto(t.size()) is a valid expression of integer-like type ([iterator.concept.winc]), ranges​::​size(E) is expression-equivalent to auto(​t.size()).

sized_range 概念和相应的 ranges::size 自定义点在 signed/unsigned 圣战中没有立场是非常有意的。 ranges::size 在计算开始和结束之间的距离时确实会转换为无符号,以与现有标准库保持一致,但用户类型不需要同意该选择。