7

According to [view.interface], non-const and const overloaded data functions are defined as follows:

template<class D>
  requires is_class_v<D> && same_­as<D, remove_cv_t<D>>
class view_interface : public view_base {
private:
  constexpr D& derived() noexcept {                   // exposition only
    return static_cast<D&>(*this);
  }
  constexpr const D& derived() const noexcept {       // exposition only
    return static_cast<const D&>(*this);
  }
public:
  constexpr auto data() requires contiguous_­iterator<iterator_t<D>> {
    return to_address(ranges::begin(derived()));
  }
  constexpr auto data() const
    requires range<const D> && contiguous_­iterator<iterator_t<const D>> {
      return to_address(ranges::begin(derived()));
    }
};

Why does data() const need to additionally satisfy that const D is a ranges::range? Isn't iterator_t<const D> already restricted so that const D must be a ranges::range?

What is the real purpose of requires range<const D> here? Is there a situation where D is a ranges::range and const D is not a ranges::range?

Boann
  • 48,794
  • 16
  • 117
  • 146
康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • For your first question: They aren't same. `ranges::range` requires implementing `ranges::end(const D&)` in addition to `ranges::begin(const D&)`, while `iterator` only requires the latter. Not sure why one would need `ranges::end` for `data() const` though. – ofo May 07 '21 at 08:59
  • @ofo. Does this mean that it is legal to use `view_interface` to wrap a _non-range_ class that cannot use `ranges::end`? I don't even know what the purpose is... – 康桓瑋 May 07 '21 at 09:10
  • I don't think so [since](https://eel.is/c++draft/range.utility#view.interface.general-2) "The template parameter `D` for `view_­interface` [...] shall [...] model [...] `view`." and `view` [requires](https://eel.is/c++draft/range.view#concept:view) `range`. – ofo May 07 '21 at 09:19
  • 2
    *Is there a situation where `D` is `ranges::range` and `const D` is not `ranges::range`?* https://godbolt.org/z/4oYKTPKTK – metalfox May 07 '21 at 09:22
  • @metalfox. Oh, this is the case why `data() const` should be forbidden, thank you! – 康桓瑋 May 07 '21 at 09:25
  • @metalfox. But in this case, `ranges::iterator_t` will still be ill-formed, so I think the purpose of `ranges::range` is just to block it early. – 康桓瑋 May 07 '21 at 09:32
  • Yes. `my_vector` is a range, but `const my_vector` isn't. – metalfox May 07 '21 at 09:47

0 Answers0