微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

C++20 引入了 ranges::split_view,它接受​​一个 view一个分隔符,并根据分隔符将 view 拆分为子范围。

分隔符也是一个view,当它是单个元素时,它会被包裹在一个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()的{​​{1}}和end()的返回类型是viewinner-iterator,但对问题不重要。问题在于两个受约束的 default_sentinel_t 函数 here

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-iterator,看起来很合理。

然而,这个约束似乎没有用,原因是copyable似乎总是满足outer-iterator。在 [range.adaptors#range.split.outer] 中,copyableouter-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: // ... }; 的基类型V没有对split_view进行建模如forward_range时,input_range只包含一个指针,所以显然是{ {1}}。当 outer-iteratorcopyable 时,V 也是 forward_range,所以它是 current_,这使得 forward_iterator 也是 {{1} }.

那么为什么标准需要基于永远无法满足的约束在 copyable 中定义一个 outer-iterator 函数

我查了之前的论文,没有找到关于这部分的讨论,不过这个copyable函数好像是在LWG3276后面加的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。