为什么 basic_istream_view 继承 view_interface?
Why does basic_istream_view inherit view_interface?
basic_istream_view
是 C++20 中的一个简单 input_range
,只有一个 begin()
和 end()
函数:
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;
};
它继承了view_interface
,在[view.interface]中定义为:
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);
};
可以看到几乎所有view_interface
的成员函数都要求D
为forward_range
,而operator bool()
要求ranges::empty(derived())
为良构, 这也要求 D
为 forward_range
.
似乎 basic_istream_view
继承 view_interface
的唯一目的是模拟一个 view
因为 view
需要 view_base
或 view_interface
被继承。
但是如果你想使 basic_istream_view
成为一个视图,为什么不直接从 view_base
继承呢?除了模板实例化的成本外,我看不出继承 view_interface
有任何好处。
那么,为什么 basic_istream_view
继承了 view_interface
而不是 view_base
?有历史原因吗?
仅仅因为 view_interface
今天的成员函数都需要前向范围并不意味着我们将来永远不会添加也可以处理输入范围的成员函数。
还有,为什么不呢?
basic_istream_view
是 C++20 中的一个简单 input_range
,只有一个 begin()
和 end()
函数:
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;
};
它继承了view_interface
,在[view.interface]中定义为:
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);
};
可以看到几乎所有view_interface
的成员函数都要求D
为forward_range
,而operator bool()
要求ranges::empty(derived())
为良构, 这也要求 D
为 forward_range
.
似乎 basic_istream_view
继承 view_interface
的唯一目的是模拟一个 view
因为 view
需要 view_base
或 view_interface
被继承。
但是如果你想使 basic_istream_view
成为一个视图,为什么不直接从 view_base
继承呢?除了模板实例化的成本外,我看不出继承 view_interface
有任何好处。
那么,为什么 basic_istream_view
继承了 view_interface
而不是 view_base
?有历史原因吗?
仅仅因为 view_interface
今天的成员函数都需要前向范围并不意味着我们将来永远不会添加也可以处理输入范围的成员函数。
还有,为什么不呢?