【问题标题】:Is std::ranges::size supposed to return an unsigned integer?std::ranges::size 是否应该返回无符号整数?
【发布时间】:2022-01-23 22:42:43
【问题描述】:

Here std::ranges::size 应该返回一个无符号整数。但是,当我在 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 的实现,我注意到返回类型是从x.size() 的返回类型推断出来的,也就是Eigen::VectorXd::Index。这是std::ranges::size 的错误吗?或者这是预期的?


2021 年 12 月 27 日更新

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

【问题讨论】:

  • 容器的size() 方法应该返回一个无符号整数。问题出在 Eigen 这边。
  • Otherwise, t.size() converted to its decayed type, if ranges::disable_sized_range&lt;std::remove_cv_t&lt;T&gt;&gt; is false, and the converted expression is valid and has an integer-like type. 对于返回大小的签名类型的容器,似乎未指定。

标签: c++ eigen c++20 eigen3 std-ranges


【解决方案1】:

sized_range 概念和相应的ranges::size 自定义点在已签名/未签名的圣战中不占任何位置。 ranges::size 确实在从开始和结束之间的距离计算时转换为无符号,以与现有标准库保持一致,但不需要用户类型同意该选择。

【讨论】:

  • 太糟糕了,我觉得如果std::ranges::size 总是返回一个无符号整数而std::ranges::ssize 总是一个无符号整数会更好!为什么不?有什么意义?
【解决方案2】:

这是 std::ranges::size 的错误吗?

没有。 cppreference 文档具有误导性。 std::ranges::size 不需要返回无符号整数。在这种情况下,它返回的正是Eigen::VectorXd::size 返回的内容。

对于模拟ranges::sized_range 的范围,这将是一个无符号整数,但Eigen::VectorXd 显然没有模拟这样的范围。

那么与 std::ranges::size 相比,std::ranges::ssize 的目的是什么?

std::ranges::ssize 的目的是作为一种通用方式来获取有符号值,而不管std::ranges::size 返回有符号还是无符号。在std::ranges::size 返回有符号类型的情况下,它们之间没有区别。

是否有参考来备份您所说的内容?

是的。请参阅 C++ 标准:

[范围.prim.size]

否则,如果 disable_­sized_­range&lt;remove_­cv_­t&lt;T&gt;&gt; ([range.sized]) 是 false 并且 auto(t.size()) 是类整数类型 ([iterator.concept.winc]) 的有效表达式,则 ranges​::​size(E) 是表达式等价的到auto(​t.size())

【讨论】:

  • 但是与std::ranges::size相比,std::ranges::ssize的目的是什么?是否有参考来备份您所说的内容?
  • 另外,Eigen::VectorXd 确实满足std::ranges::sized_range 概念!
  • 实际上是这样:满足std::ranges::sized_range 概念的唯一要求是Eigen::VectorXd 是一个范围(从Eigen 3.4 开始就是这样)并且std::ranges::size 可以在Eigen::VectorXd 上调用对象。
  • 公平地说,cppreference 文档只是提到std::ranges::size() "只要ranges::size(e) 对表达式e 有效,返回类型就类似于整数.", 而std::ranges::ssize() "如果ranges::ssize(e) 对表达式e 有效,返回类型是类似有符号整数的类型 b>,即 std::is_signed_v 为真的整数类型,或有符号整数类类型。"
  • @Bob__ 是的,这些是准确的。误导部分在问题中链接的范围库页面上。
猜你喜欢
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 2016-09-15
  • 2012-08-26
  • 2015-12-22
  • 1970-01-01
  • 2014-03-05
相关资源
最近更新 更多