2

我遇到了以下代码:

for (int i = 0; i < subspan.size(); i++) {
  ...
  int size = size_table[&(subspan[i]) - fullspan.begin()];
  ...
}

subspan并且fullspan都是类型std::span(实际上absl::Span来自Google 的 Abseil 库,但它们似乎与 几乎相同std::span)并且是同一数据数组的视图(fullspan跨越整个数组)。

这是有效且定义明确的代码吗?-当运算符与 lhs 指针一起应用时,它似乎取决于将迭代器转换为相应的指针值。

4

2 回答 2

2

从元素指针中减去迭代器以获得有效索引是否有效?

它可能是,取决于迭代器的定义方式。例如,如果迭代器是相同类型的指针,并且指向相同数组的元素,它就可以工作。

但是,没有通用迭代器概念指定此类操作,因此不能保证此类操作适用于任何标准迭代器。因此,它不是一个可移植的假设,即它可以在通用代码中工作。

这是有效且定义明确的代码吗?

所讨论的迭代器类型被定义为指针类型,因此满足该条件。Abseil 既没有完整的文档记录也没有具体说明,因此很难说这是一个有意的功能,还是附带的实现细节。如果是后者,那么代码可能会在 Abseil 的未来版本中中断。

于 2021-11-23T12:47:50.080 回答
0

阅读的实现absl::Span,我们有:

template <typename T>
class Span {
...
 public:
  using element_type = T;
  using pointer = T*;
  using const_pointer = const T*;
  using reference = T&;
...
  using iterator = pointer;
...
  constexpr iterator begin() const noexcept { return data(); }
  constexpr reference operator[](size_type i) const noexcept { return *(data() + i); }
...
}

所以你的表达式归结为简单的指针算术。请注意,没有检查两个跨度是否引用相同的基本跨度,但您断言情况并非如此。

于 2021-11-23T12:51:25.250 回答