什么情况下ranges::split_view的迭代器不满足copyable?

C++20 引入了 a ranges::split_view,它接受 aview和一个定界符,并view根据定界符将 a分成子范围。

分隔符也是 a view,当它是单个元素时,它会被包裹在 a 中ranges::single_view

每个返回的子范围也是一个view,它的类型是split_view::outer-iterator::value_type,在[range.adaptors#range.split.outer.value] 中定义:

template<bool Const>
struct split_view<V, Pattern>::outer-iterator<Const>::value_type
  : view_interface<value_type> {
private:
  outer-iterator i_ = outer-iterator();               // exposition only
public:
  value_type() = default;
  constexpr explicit value_type(outer-iterator i) : i_(std?::?move(i)) {}

  constexpr inner-iterator<Const> begin() const requires copyable<outer-iterator>
  constexpr inner-iterator<Const> begin() requires (!copyable<outer-iterator>);
  constexpr default_sentinel_t end() const;
};

的返回类型begin()end()这种内在的viewinner-iteratordefault_sentinel_t,但它不是的问题很重要。问题在于这里的两个约束begin()函数:

constexpr inner-iterator<Const> begin() const requires copyable<outer-iterator>
{ return inner-iterator<Const>{i_­}; }

constexpr inner-iterator<Const> begin() requires (!copyable<outer-iterator>);
{ return inner-iterator<Const>{std::move(i_)­}; }

begin()功能选择是否移动底层i_根据其类型是否 outer-iteratorcopyable,看起来合理的。

然而,这个约束似乎没有用,原因是outer-iterator似乎总是满足copyable。在[range.adaptors#range.split.outer] 中,作为outer-iterator的迭代器类型的split_view被定义为:

template<bool Const>
struct split_view<V, Pattern>::outer-iterator {
private:
  using Parent = maybe-const<Const, split_view>;      // exposition only
  using Base = maybe-const<Const, V>;                 // exposition only
  Parent* parent_ = nullptr;                          // exposition only
  iterator_t<Base> current_ = iterator_t<Base>();     // exposition only, present only if V models forward_­range
  
public:
// ...
};

当基类型Vsplit_view不车型forward_range,如input_range,将outer-iterator只包含一个指针,所以这显然是copyable。当V是 a 时forward_range,thecurrent_也是 a forward_iterator,所以是copyable,这使得outer-iterator也是copyable

那么为什么标准需要根据永远无法满足的约束来定义一个begin()函数split_view::outer-iterator::value_type呢?

查了之前的论文,没有发现这部分的讨论,不过这个begin()功能好像是在LWG3276之后加的。

以上是什么情况下ranges::split_view的迭代器不满足copyable?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>