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?