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?
CodePudding user response:
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?
