0

basic_istream_view is a simple input_range in C++20 and has only one begin() and end() function:

template<movable Val, class CharT, class Traits>
  requires default_­initializable<Val> &&
           stream-extractable<Val, CharT, Traits>
class basic_istream_view : public view_interface<
                                    basic_istream_view<Val, CharT, Traits>> { 
 public:
  constexpr iterator begin();
  constexpr default_sentinel_t end() const noexcept;
};

It inherits view_interface which is defined in [view.interface] as:

template<class D>
class view_interface {
 public:
  constexpr bool empty() requires forward_­range<D>;

  constexpr explicit operator bool()
    requires requires { ranges::empty(derived()); };

  constexpr auto data() requires contiguous_­iterator<iterator_t<D>>;

  constexpr auto size() requires forward_­range<D>;

  constexpr decltype(auto) front() requires forward_­range<D>;
  constexpr decltype(auto) back() requires bidirectional_­range<D>;

  template<random_­access_­range R = D>
  constexpr decltype(auto) operator[](range_difference_t<R> n);
};

You can see that almost all member functions of view_interface require D to be forward_range, while operator bool() requires ranges::empty(derived()) to be well-formed, which also requires D to be forward_range.

It seems that the only purpose of basic_istream_view inheriting view_interface is to model a view since view requires view_base or view_interface to be inherited.

But if you want to make basic_istream_view a view, why not just inherit it directly from view_base? I can't see any benefit from inheriting view_interface except for the cost of template instantiation.

So, why does basic_istream_view inherit the view_interface instead of view_base? Does it have historical reasons?

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
  • To me it looks like it's providing suitable implementations for member functions via CRTP. Also note DR [LWG 3549](https://cplusplus.github.io/LWG/issue3549): "_`view_interface` was required to be derived from `view_base`, which sometimes required multiple `view_base` subobjects in a view._". This inheritance is now removed from the standard – Ted Lyngmo Sep 23 '21 at 16:34
  • 1
    "*What are the considerations behind this?*" I don't really understand your question. It's a view. Views ought to inherit from `view_interface`. What more "considerations" do you need? – Nicol Bolas Sep 23 '21 at 16:36
  • @Nicol Bolas. I mean "*why does the basic_istream_view inherit the view_interface instead of view_base?*" – 康桓瑋 Sep 23 '21 at 16:43
  • And my question to you is... why *shouldn't* it? That is, just because the member functions aren't available doesn't mean that it's inappropriate to inherit from it. – Nicol Bolas Sep 23 '21 at 16:45
  • @NicolBolas. I understand what you mean. In my opinion, simply inheriting `view_base` seems to be a better choice, but this may just be my one-sided word, thank you for your enlightenment. – 康桓瑋 Sep 23 '21 at 16:48

1 Answers1

3

Just because the member functions of view_interface today all need forward ranges doesn't mean that we will never add member functions in the future that can work on input ranges too.

Also, why not?

T.C.
  • 133,968
  • 17
  • 288
  • 421