【问题标题】:Why does std::span lack the comparison operators?为什么 std::span 缺少比较运算符?
【发布时间】:2020-06-23 07:08:35
【问题描述】:

std::span 不是设计为对std::vector/std::array/纯数组 等的子区域的轻量级引用吗?它不应该在其 API 中包含比较运算符,以与它们保持一致吗?排除的原因是什么?

注意:通过比较运算符,我的意思是完整集(<<=、...)或宇宙飞船<=>

【问题讨论】:

  • IMO 的好问题,我也想知道。 operator== 也不见了。特别是。对于矢量,我经常发现直接比较很方便。这可能是由于静态大小跨度类型的困难,尽管我不确定。
  • 看起来像gsl::span,其中std::span的版本也不包括这些。
  • @DanielLangr 为什么不像std::vectorstd::array 这样的字典比较呢?它们已经为这些类型定义了,所以为什么不在这里。
  • 请注意,P0122R7 建议比较 span,但 current draft standard 不包括它。
  • @darune gsl::span 确实(并且一直如此)有比较运算符。他们只是将它们移到了own header

标签: c++ std c++20 std-span


【解决方案1】:

As Daniel Langr pointed outstd::span 在其初始提案P0122 中有比较运算符。然后这些运算符从工作草案N4791 开始被删除,原因在P1085 中说明。

简而言之,std::span 的 copy 和 const 是“浅层的”(意味着复制 std::span 不会复制其底层元素,而 const std::span 不会阻止其底层元素被修改),所以比较,如果存在的话,也应该是“浅的”以保持一致性。

那篇论文给出了以下例子:

示例 1:

T oldx = x;
change(x);
assert(oldx != x);
return oldx;

示例 2:

void read_only(const T & x);

void f()
{
  T tmp = x;
  read_only(x);
  assert(tmp == x);
}

如果T = std::span,这些示例中的断言可能会失败,而对于常规类型则不会。

有人可能会争辩说std::string_view 具有浅拷贝但深度比较。 P1085对此也有解释:

这匹配string_view,但是string_view 不能修改它指向的元素,因此string_view 的浅拷贝可以被认为类似于写时复制优化。

【讨论】:

  • 请注意,当std::string_view 指向它时,没有什么可以阻止字符数组的所有者修改原始存储。所以,比如说,std::map<std::span<T>, U>std::map<std::string_view, U> 一样破碎。恕我直言,std::string_view 也不应该包含比较运算符。
  • 跟进:对于其他模板参数U,这两个示例都适用于T = std::span<const U>。对于这种情况,operator== 不合理吗?是否也考虑过这一点?
  • A span<const T> 没有描述的问题。
猜你喜欢
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多