ãã®è¨äºã¯C++ Advent Calendar 2021ã®7æ¥ç®ã®è¨äºã§ãã
owning_view
owning_view
ã«ã¤ãã¦ã¯ãã¡ããã©å¥ã«æ¸ããã®ã§ä»¥ä¸ããåç
§ãã ããã
owning_view
ã¯å³è¾ºå¤ã®ç¯å²ããæ§ç¯ããããããææãããã¨ã§å³è¾ºå¤ç¯å²ã®å¯¿å½ã延é·ãããã®ã§ããå®ç¾©ã¯ç°¡åãªã®ã§ã³ãããã¦ããã¨æ¬¡ã®ããã«ãªã£ã¦ãã¾ã
namespace std::ranges { template<range R> requires movable<R> && (!is-initializer-list<R>) // see [range.refinements] class owning_view : public view_interface<owning_view<R>> { private: R r_ = R(); // exposition only public: owning_view() requires default_initializable<R> = default; // å°ã使ç¨ããã³ã³ã¹ãã©ã¯ã¿ constexpr owning_view(R&& t) : r_(std<200b>::<200b>move(t)) {} // ã ã¼ãã³ã³ã¹ãã©ã¯ã¿/ä»£å ¥æ¼ç®å owning_view(owning_view&&) = default; owning_view& operator=(owning_view&&) = default; // ä¿æããRã®ãªãã¸ã§ã¯ããåå¾ãã constexpr R& base() & noexcept { return r_; } constexpr const R& base() const& noexcept { return r_; } constexpr R&& base() && noexcept { return std::move(r_); } constexpr const R&& base() const&& noexcept { return std::move(r_); } // Rã®ã¤ãã¬ã¼ã¿ããã®ã¾ã¾ä½¿ç¨ constexpr iterator_t<R> begin() { return ranges::begin(r_); } constexpr sentinel_t<R> end() { return ranges::end(r_); } // Rãconst-iterableãªããããªã constexpr auto begin() const requires range<const R> { return ranges::begin(r_); } constexpr auto end() const requires range<const R> { return ranges::end(r_); } constexpr bool empty() requires requires { ranges::empty(r_); } { return ranges::empty(r_); } constexpr bool empty() const requires requires { ranges::empty(r_); } { return ranges::empty(r_); } // Rãsized_rangeãªããããªã constexpr auto size() requires sized_range<R> { return ranges::size(r_); } constexpr auto size() const requires sized_range<const R> { return ranges::size(r_); } // Rãcontiguous_rangeãªããããªã constexpr auto data() requires contiguous_range<R> { return ranges::data(r_); } constexpr auto data() const requires contiguous_range<const R> { return ranges::data(r_); } }; }
ã ã¼ãã³ã³ã¹ãã©ã¯ã¿ãé¤ãã¨ã³ã³ã¹ãã©ã¯ã¿ã¯ä¸ã¤ãããªããããã§ã¯R
ï¼range
ãã¤movable
ï¼ã®å³è¾ºå¤ï¼ããã¯ãã©ã¯ã¼ãã£ã³ã°ãªãã¡ã¬ã³ã¹ã§ã¯ããã¾ããï¼ãåãåãããããã¡ã³ãå¤æ°r_
ã«ã ã¼ããã¦ä¿æãã¾ãããã®ããã«ãã¦å
¥åã®å³è¾ºå¤ç¯å²ã®å¯¿å½ã延é·ãã¦ããããã以å¤ã®é¨åã¯è¦ã¦ãããããã«å
ã®R
ã®èãã©ããã§ãã
views::all
ã¨views::all_t
owning_view
ãçæããããã®Rangeã¢ããã¿ã¨ãã¦views::all
ãç¨æããã¦ãã¾ãããviews::all
ã¯owning_view
ã ãã§ãªãref_view
ãè¿ãã¾ãã
åR
ã®ãªãã¸ã§ã¯ãr
ã«å¯¾ãã¦ãviews::all(r)
ã®ããã«å¼ã°ããæã®å¹æã¯
R
ãview
ã®ã¢ãã«ã§ãããªããr
ãdecay-copyãã¦è¿ã- decay-copyã¯
r
ãã³ãã¼orã ã¼ããã¦ãã®åã®æ°ãããªãã¸ã§ã¯ããä½ã£ã¦ãããè¿ããã¨
- decay-copyã¯
r
ã左辺å¤ãªãref_view(r)
r
ãå³è¾ºå¤ãªãowning_view(std::move(r))
ãã®ããã«ãviews::all
ã¯range
ãå
¥åã¨ãã¦view
ãè¿ããã®ã§ãå¥ã®è¨ãæ¹ãããã¨range
ãview
ã«å¤æãããã®ã§ããviews::all
ã主ä½ã¨ãã¦ã¿ãã°ãref_view
ã¨ãowning_view
ã®åºå¥ã¯éè¦ã§ã¯ãªãããããã®2ã¤ãã¾ã¨ãã¦ï¼ãããã¯ãviews::all
ã«ããview
ãï¼All viewã¨å¼ã³ã¾ãã
<ranges>
ã®Rangeã¢ããã¿ã¨å¼ã°ããview
ã¯ãä»»æã®view
ãå
¥åã¨ãã¦ä½ãæä½ãé©ç¨ããview
ãè¿ããã®ã§ãããã®ãããRangeã¢ããã¿ï¼ã®å®æ
ã®view
åï¼ã«range
ã渡ãããã«ã¯ä¸åº¦view
ã«å¤æããå¿
è¦ããããviews::all
ã¯ãã®å¤æãæ
ãRangeã¢ããã¿ã¨ãã¦æ¨æºã«è¿½å ããã¦ãã¾ããã¨ã¯ãããã¦ã¼ã¶ã¼ãRangeã¢ããã¿ã使ç¨ããéã«ä¸ã
views::all
ã使ç¨ããªããã°ãªããªãã®ãã¨ããã°ããã§ã¯ãªãããã®é©ç¨ã¯All viewãé¤ãå
¨ã¦ã®Rangeã¢ããã¿ã«ããã¦èªåã§è¡ããã¾ãããã®ããé常ã¯ãã¦ã¼ã¶ã¼ãviews::all
ããã³ref_view
ãowning_view
ãç´æ¥ä½¿ãæ©ä¼ã¯ç¨ãªã¯ãã§ãã
views::all
ã®èªåé©ç¨ã¯æ¨è«è£å©ããã¾ãå©ç¨ãã¦è¡ããã¦ãã¾ããç°¡æãªå®è£
ãæ¸ãã¦ã¿ãã¨
using namespace std::ranges; // ä»»æã®view template<view V> class xxx_view { V base_; public: // å ¥åviewãåãåãã³ã³ã¹ãã©ã¯ã¿ xxx_view(V v) : base_(std::move(v)) {} }; // ãã®æ¨è«è£å©ãéè¦ï¼ template<range R> xxx_view(R&&) -> xxx_view<views::all_t<R>>;
views::all_t
ã¯views::all
ã®æ»ãå¤åãæ±ãããã®ã§ã次ã®ããã«å®ç¾©ããã¾ãã
namespace std::ranges::views { template<viewable_range R> using all_t = decltype(all(declval<R>())); }
ãã®xxx_view
ãxxx_view{r}
ã®ããã«ä½¿ç¨ããæãã¯ã©ã¹ãã³ãã¬ã¼ãã®å®å¼æ°æ¨å®ãèµ·ãããã¨ã«ãã£ã¦1ã¤ã ãå®ç¾©ããã¦ããæ¨è«è£å©ã使ç¨ãããr
ã®åR
ãviews::all_t<R>
ã®ããã«éãã¦ãviews::all(r)
ã®æ»ãå¤åãxxx_view
ã®ãã³ãã¬ã¼ããã©ã¡ã¼ã¿V
ã¨ãã¦åå¾ãã¾ããviews::all
ã®æ»ãå¤åã¯ãr
ãview
ãªããã®view
åï¼prvalueã¨ãã¦ã®ç´ ã®åï¼ãr
ã左辺å¤ãªãref_view{r}
ãr
ãå³è¾ºå¤ãªãowning_view{r}
ãè¿ãã¾ããã¤ã¾ããviews::all_t<R>
ã¯å¸¸ã«R
ãå¤æããview
ã®CV修飾ãªãåç
§ãªãã®ç´ ã®åï¼prvalueï¼ãå¾ã¾ãã
ãããã¦å¾ãããåãV
ã¨ããã¨ãxxx_view{r}
ã¯xxx_view<V>{r}
ã®ãããªåæåå¼ã«ãªãã¾ããxxx_view
ï¼ããã³æ¨æºRangeã¢ããã¿ã®view
ï¼ã®view
ãåãåãã³ã³ã¹ãã©ã¯ã¿ã¯explicit
ããªãããã³ãã¬ã¼ããã©ã¡ã¼ã¿ã«æå®ãããview
åï¼V
ãããã¯å®å¼æ°r
ã®åR
ã«å¯¾ãã¦views::all_t<R>
ã®åï¼ãå¤ã¨ãã¦åãããã®ã§ããããããã®ã³ã³ã¹ãã©ã¯ã¿å¼æ°ã§ã¯R -> V
ã®æé»å¤æã«ãã£ã¦views::all(r)
ãéããã®ã¨åããã¨ãèµ·ãããããã§views::all
ã®èªåé©ç¨ãè¡ããã¾ãã
ããã¨åããã¨ããAll viewãé¤ãå
¨ã¦ã®Rangeã¢ããã¿ã®view
åã§å®è£
ããã¦ãããããã«ãã£ã¦ãRangeã¢ããã¿ã¯views::all
ãèªåé©ç¨ãã¦view
ãåãåã£ã¦ãã¾ããããã¯xxx_view
ã«å¯¾ãã¦views::xxx
ã®ååã®Rangeã¢ããã¿ã使ç¨ããæã§ãåæ§ã§ãï¼ãã®å¹æã§ã¯çµå±ãä½ãããã®view
åãé©ç¨ãããã¨ã«ãªãããï¼ã
#include <ranges> #include <vector> auto f() -> std::vector<int>&; auto g() -> std::vector<int>; using namespace std::ranges; int main() { auto tv = take_view{f(), 5}; // decltype(tv) == take_view<ref_view<std::vector<int>>> auto dv = drop_view{g()}, 2; // decltype(dv) == drop_view<owning_view<std::vector<int>>> auto dtv = drop_view{tv, 2}; // decltype(dtv) == drop_view<take_view<ref_view<std::vector<int>>>> auto ddv = dv | views::drop(2); // decltype(ddv) == drop_view<drop_view<owning_view<std::vector<int>>>> auto ddv2 = drop_view{dv, 2}; // decltype(ddv2) == drop_view<drop_view<owning_view<std::vector<int>>>> }
ãã¤ãã©ã¤ã³ã§èµ·ãããã¨
åå¥ã®view
åã§èµ·ãããã¨ã¯ããã£ãããããã¾ããããå®éã«ä½¿ç¨ããæã«èµ·ãããã¨ã¯ã¤ã¡ã¼ã¸ãã¥ãããã®ãããã¾ãã
#include <ranges> #include <vector> auto f() -> std::vector<int>; auto even = [](int n) { return 0 < n; }; auto sq = [](int n) { return n * n; }; using namespace std::views; int main() { // pipesã®åã¯ï¼æ§é ã¯ï¼ï¼ auto pipes = f() | drop(2) | filter(even) | transform(sq) | take(5); // å®å ¨ãf()ã®æ»ãå¤ã¯owning_viewã«ãã£ã¦å¯¿å½å»¶é·ããã¦ãã for (int m : pipes) { std::cout << n << ','; } }
ä¾ãã°ãã®ãããªRangeã¢ããã¿ã«ãããã¤ãã©ã¤ã³ã®çµæã¨ãã¦å¾ãããpipes
ã¯ãã©ããªåãæã¡ã©ããªæ§é ã«ãªã£ã¦ããã®ã§ããããï¼ã¾ããf()
ã®çµæï¼å³è¾ºå¤ï¼ã¯owning_view
ã«ãã£ã¦å®å
¨ã«åãåããã¦ããã¯ãã§ãããpipes
ã®ã©ãã«ããã¯ä¿æããã¦ããã®ã§ããããï¼
å
ç¨ã®views::all/views::all_t
ã®æ¨æºRangeã¢ããã¿ã§ã®ä½¿ããæ¹ãæãåºãã¨ãpipes
ã®åã¯ãããããã§ãã
1è¡ç®ã®f() | drop(2)
ã§ã¯drop_view
ï¼views::drop(2)
ã«ããï¼ã®æ§ç¯ãè¡ãããf()
ã®æ»ãå¤ãr
ã¨ããã¨drop_view{r, 2}
ãæ§ç¯ããã¾ããåè¿°ã®éããããã§ã¯views::all
ãèªåé©ç¨ãããr
ã¯å³è¾ºå¤std::vector<int>
ãªã®ã§ãã®çµæã¯owning_view{r}
ã帰ãã¾ãããããã£ã¦ããã®è¡ã§çæããããªãã¸ã§ã¯ãã®åã¯drop_view<owning_view<std::vector<int>>>
ã¨ãªãã¾ãã
ãã®çµæãv1
ã¨ãã¦ã次ã®è¡v1 | filter(even)
ã§ã¯filter_view
ããfilter_view{v1, even}
ã®ããã«æ§ç¯ããã¾ããããã§ãviews::all
ãèªåé©ç¨ããã¦ãã¾ãããviews::all(v1)
ã¯v1
ãæ¢ã«view
ã§ãããããããããã®ã¾ã¾ï¼decay-copyããã¦ï¼å¸°ãã¾ãããããã£ã¦ããã®è¡ã§çæããããªãã¸ã§ã¯ãã®åã¯filter_view<drop_view<owning_view<std::vector<int>>>, even_t>
ã¨ãªãã¾ãï¼è¿°èªeven
ã®ã¯ãã¼ã¸ã£åãeven_t
ã¨ãã¦ãã¾ãï¼ã
ãã¤ãã©ã¤ã³ã®2段ç®ä»¥éã§ã¯views::all
ã®é©ç¨ã¯ã»ã¼æçå¤æã¨ãªããããviews::all_t
ã®åãæ°ã«ããå¿
è¦ãããã®ã¯ãã¤ãã©ã¤ã³ã®ä¸çªæåã ãã§ããå¾ã®è¡ããã³ãã®ä»ã®Rangeã¢ããã¿ã®é©ç¨æã«èµ·ãããã¨ãåãããã«ãªãããããã®2è¡ç®ã§èµ·ãã¦ããäºããããã°å¾ã¯ç°¡åã§ãããã ããRangeã¢ããã¿ãªãã¸ã§ã¯ãã®è¿ãåã«æ³¨æãå¿
è¦ã§ã¯ããã¾ãã
auto pipes = f() | drop(2) // V1 = drop_view<owning_view<std::vector<int>>> | filter(even) // V2 = filter_view<V1, even_t> | transform(sq) // V3 = transform_view<V2, sq_t> | take(5); // V4 = take_view<V3>
ç¥ããã«æ¸ãã¨decltype(pipes) == take_view<transform_view<filter_view<drop_view<owning_view<std::vector<int>>>, even_t>, sq_t>>
ã¨ãªãã¾ããæ¨æºview
åã¯å
¥åã®view
ããã³ãã¬ã¼ãã®1ã¤ç®ã®å¼æ°ã¨ãã¦åãã®ã§ããã¤ãã©ã¤ã³å段ã®view
åãã次ã®æ®µã®view
åã®ç¬¬ä¸ãã³ãã¬ã¼ãå¼æ°ã¨ãã¦ã¯ã¾ã£ã¦ããã¾ãã
åããããã°ããã®ãªãã¸ã§ã¯ãæ§é ããªãã¨ãªãè¦ãã¦ãã¾ããããããæ¨æºview
åã®åã
ã®ã¯ã©ã¹æ§é ãããããªãã¨ãã®ãã¤ãã©ã¤ã³å
¨ä½ã®æ§é ãæ¨ãéãäºãã§ãã¾ããã
æ¨æºview
åï¼ä¸»ã«Rangeã¢ããã¿ï¼ã®åã¨ãã¦ã®æ§é ï¼ç¬¬ä¸ãã³ãã¬ã¼ãå¼æ°ã«å
¥åview
ãã¨ããæ¨è«è£å©ã«ãã£ã¦views::all_t
ãèªåé©ç¨ããï¼ãããç¨åº¦ä¸è²«ãã¦ããããã«ããã®ã¯ã©ã¹æ§é ãã¾ãããç¨åº¦ã®ä¸è²«æ§ãããã¾ããããã§ã¯ãå
¥åã®view
ãªãã¸ã§ã¯ããã³ã³ã¹ãã©ã¯ã¿ã§å¤ã¨ãã¦åãåã£ã¦ãã¡ã³ãå¤æ°ã«ã ã¼ããã¦ä¿æãã¦ãã¾ãã
using namespace std::ranges; // ä»»æã®view template<view V, ...> class xxx_view { // å ¥åviewãã¡ã³ãã¨ãã¦ä¿æ V base_ = V(); public: // å ¥åviewï¼ã¨è¿½å ã®å¼æ°ï¼ãåãåãã³ã³ã¹ãã©ã¯ã¿ xxx_view(V v, ...) : base_(std::move(v)) {} };
view
ã³ã³ã»ããã®å®ç¾©ããview
ã¨ã¯ãã ã¼ãæ§ç¯ãO(1)
ã§è¡ãã¦ãã ã¼ããããåæ°N
ã¨è¦ç´ æ°M
ããï¼ã ã¼ãå¾view
ãå«ãï¼N
åã®ãªãã¸ã§ã¯ãã®ç ´æ£ãO(N+M)
ã§è¡ãã¦ãã ã¼ã代å
¥ã®è¨ç®éã¯æ§ç¯ã¨ç ´æ£ãè¶
ããªãç¨åº¦ãã§ãããããªåã§ããowning_view
ã®ãããªä¾å¤ãé¤ãã°ãããã¯ç¯å²ãææããã«range
ã¨ãªããããªåãæå®ãã¦ãããã ã¼ãæ§ç¯ã®ã³ã¹ãã¯ç¯å²ã®è¦ç´ æ°ã¨ç¡é¢ä¿ã«è¡ããäºã示ãã¦ãã¾ãï¼ããã§ã¯view
ã®ã³ãã¼ã«ã¤ãã¦ã¯è§¦ããªããã¨ã«ãã¾ãï¼ã
owning_view
ã¯ç¯å²ãææãã¾ãããã ã¼ããªã³ãªã¼ã§ããããview
ã³ã³ã»ããã®è¦ä»¶ãæºãããã¨ãã§ãããå°ãç¹æ®ãªview
åã§ãã
views::all_t<R>
ã¯R
ãview
ã§ããæã«R
ã®ç´ ã®åï¼prvalueã¨ãã¦ã®åï¼ãè¿ãã¾ããããã¯å³è¾ºå¤R&&
ã¨å·¦è¾ºå¤R&
ããã³const R
ã«å¯¾ãã¦ãR
ã¨ãªãåã§ãããã®ãããªCV修飾ãªãåç
§ãªãã®åãview
åã®å
¥åV
ã¨ãªããããV
ã®ãªãã¸ã§ã¯ãrv
ï¼ããã¯ãã¤ãã©ã¤ã³å
ã§ã¯å³è¾ºå¤ï¼ã¯ã³ã³ã¹ãã©ã¯ã¿å¼æ°v
ã«å¯¾ãã¦ã¾ãã ã¼ããããã¡ã³ãbase_
ã¨ãã¦ä¿æããããã«ããä¸åº¦ã ã¼ãããã¾ããV
ãref_view
ãã¯ããã¨ããç¯å²ãææããªãã¿ã¤ãã®view
ã§ããæããã®åç
§ãå«ãview
ãªãã¸ã§ã¯ããã¨ã ã¼ãï¼ã³ãã¼ï¼ããã¡ã³ãã¨ãã¦ä¿åããã¾ããV
ãowning_view
ã®ããã«ç¯å²ãææããview
ã®å ´åããã®ææ権ãã¨view
ãªãã¸ã§ã¯ããã ã¼ããã¦ã¡ã³ãã¨ãã¦ä¿åãã¾ãããã®å¾ããããã¦æ§ç¯ãããview
ãªãã¸ã§ã¯ãã¯ããã¤ãã©ã¤ã³ã®æ¬¡ã®æ®µã§åæ§ã«æ¬¡ã®view
ãªãã¸ã§ã¯ãå
é¨ã«ã ã¼ããã¦ä¿æããã¾ãã
ãã¤ãã©ã¤ã³ã®æ ¼æ®µã§ãã®ãããªä¸æview
ãªãã¸ã§ã¯ãã®ã ã¼ããèµ·ãã¦ãããããæåã«æ§ç¯ãããref_view or owning_view
ãªãã¸ã§ã¯ãã¯æå¾ã¾ã§æ¨ã¦ããããã¨ãªãããã¤ãã©ã¤ã³ã®ä¸çªæå¾ã«ä½æããããªãã¸ã§ã¯ãå
ã«ä¿æããã¾ããããã¦ããã¤ãã©ã¤ã³ã®æ®µãéãªããã¨ã«ããããå
ãããã«Rangeã¢ããã¿ã®view
ã®å±¤ãç©ã¿éãªã£ã¦ããã¾ãã
ã¤ã¡ã¼ã¸ã¨ãã¦ã¯ãããªã§ã¼ã·ã«ã¨ãçããã¨ããããªæãã§ãä¸çªä¸å¿ã«ãã¤ãã©ã¤ã³ã®èµ·ç¹ã¨ãªã£ãå
¥årange
ãåç
§orææããview
ãªãã¸ã§ã¯ããå±
ã¦ãããã¯é常ref_view
ãowning_view
ã®ã©ã¡ããã¨ãªãã¾ãã
#include <ranges> #include <vector> auto f() -> std::vector<int>; auto even = [](int n) { return 0 < n; }; auto sq = [](int n) { return n * n; }; using namespace std::views; int main() { // f()ã®æ»ãå¤ã¯pipesã®å¥¥æ·±ãã«ãã¾ããã¦ããã»ã»ã» auto pipes = f() | drop(2) | filter(even) | transform(sq) | take(5); // å®å ¨ãf()ã®æ»ãå¤ã¯çåæéå for (int m : pipes) { std::cout << n << ','; } }
æ§é ãç°¡åã«æ¸ãã¦ã¿ãã¨æ¬¡ã®ããã«ãªã£ã¦ãã¾ã
pipes : take_view
base_ : transform_view
base_ : filter_view
base_ : drop_view
base_ : owning_view
r_ : std::vector<int>
pred_ : even_t
fun_ : sq_t
ï¼å¤æ°åã¯è¦æ ¼æ¸ã®ãã®ãåèã«ãã¦ãã¾ããããã®ååã§åå¨ããããã§ã¯ããã¾ããï¼
ãã®ããã«ãã¦ãf()
ã®æ»ãå¤ã§ããå³è¾ºå¤ã®std::vector
ãªãã¸ã§ã¯ãã®å¯¿å½ã¯ããã¤ãã©ã¤ã³ãéãã¦ã延é·ããã¦ãã¾ããviews::filter
ãåãåãè¿°èªãªãã¸ã§ã¯ããªã©ã対å¿ãã層ï¼view
ãªãã¸ã§ã¯ãå
é¨ï¼ã«ä¿åããã¦ãããåæ§ã«å®å
¨ã«åãåãã使ç¨ããäºãã§ãã¾ãã
ref_view
ã®å ´å
å
ã»ã©ã®ä¾ã®f()
ã左辺å¤ãè¿ãã¦ããå ´åããã¤ãã©ã¤ã³æåã®drop_view
æ§ç¯æã®views::all
é©ç¨æã«ã¯ãref_view
ãé©ç¨ããã¾ãã
#include <ranges> #include <vector> auto f() -> std::vector<int>&; auto even = [](int n) { return 0 < n; }; auto sq = [](int n) { return n * n; }; using namespace std::views; int main() { // f()ã®æ»ãå¤ã¯åç §ããã¦ãã auto pipes = f() | drop(2) | filter(even) | transform(sq) | take(5); // f()ã§è¿ãããvectorã®å ãçãã¦ããã°å®å ¨ for (int m : pipes) { std::cout << n << ','; } }
ãã®æã®pipes
ã®åã¯å
ã»ã©owning_view<std::vector<int>>
ã ã£ãã¨ãããref_view<std::vector<int>>
ã«ä»£ããã ãã§ãä»èµ·ãããã¨ã¯åãã§ãã
ref_view
ã¯æ¬¡ã®ããã«å®ç¾©ããã¦ãã¾ãã
namespace std::ranges { // ã³ã³ã¹ãã©ã¯ã¿å¶ç´ã®èª¬æå°ç¨ã®é¢æ° void FUN(R&); void FUN(R&&) = delete; template<range R> requires is_object_v<R> class ref_view : public view_interface<ref_view<R>> { private: // åç §ã¯ãã¤ã³ã¿ã§ä¿æãã R* r_; // exposition only public: // 左辺å¤ãåãåãã³ã³ã¹ãã©ã¯ã¿ template<different-from<ref_view> T> requires convertible_to<T, R&> && // T(å³è¾ºå¤or左辺å¤åç §)ãR&(左辺å¤åç §)ã¸å¤æå¯è½ã§ããã㨠requires { FUN(declval<T>()); } // tãå³è¾ºå¤ãªãFUN(R&&)ãé¸æããå¶ç´ãæºãããªã constexpr ref_view(T&& t) : r_(addressof(static_cast<R&>(std<200b>::<200b>forward<T>(t)))) {} constexpr R& base() const { return *r_; } constexpr iterator_t<R> begin() const { return ranges::begin(*r_); } constexpr sentinel_t<R> end() const { return ranges::end(*r_); } constexpr bool empty() const requires requires { ranges::empty(*r_); } { return ranges::empty(*r_); } constexpr auto size() const requires sized_range<R> { return ranges::size(*r_); } constexpr auto data() const requires contiguous_range<R> { return ranges::data(*r_); } }; // æ¨è«è£å©ã左辺å¤åç §ããããæ¨è«ã§ããªã template<class R> ref_view(R&) -> ref_view<R>; }
ã³ã³ã¹ãã©ã¯ã¿ã¯ããªããããããã§ãããæ¨è«è£å©ã¨çµã¿åããã£ã¦ã確å®ã«å·¦è¾ºå¤ã®ãªãã¸ã§ã¯ãã ããåãåãããã«ãªã£ã¦ãã¾ããããã¦ãref_view
ã¯åç
§ããç¯å²ã¸ã®ãã¤ã³ã¿ãä¿æãã¦ã©ãããããã¨ã§range
åR
ãview
ã¸ã¨å¤æãã¾ããã¾ããããã¦å®ç¾©ããã¦ã¯ãã¾ããããref_view
ã®ã³ãã¼/ã ã¼ãã»ã³ã³ã¹ãã©ã¯ã¿/代å
¥æ¼ç®åã¯æé»å®ç¾©ããã¦ãã¾ãã
ãã¤ãã©ã¤ã³ã¸ã®å
¥åã左辺å¤ã§ããå ´åããã¤ãã©ã¤ã³ã«ãã£ã¦çæããããããªã§ã¼ã·ã«ã®ä¸å¿ã«ã¯ref_view
ããããããããã¯å
ã®ç¯å²ããã¤ã³ã¿ã«ãã£ã¦åç
§ãã¦ããããã§ãã
ref_view
ã¯ããã©ã«ãæ§ç¯ä¸å¯è½ã§ããã®ã§ãã¡ã³ãã®ãã¤ã³ã¿r_
ãnullptr
ã¨ãªããã¨ãèæ
®ããå¿
è¦ã¯ãªãã§ãããåç
§å
ã®range
ãªãã¸ã§ã¯ããå
ã«å¯¿å½ãè¿ããã°å®¹æã«ãã³ã°ãªã³ã°ã¨ãªãã¾ããã¾ãããã¤ã³ã¿ã®é¢ç¯åç
§ã®ã³ã¹ããï¼ããããæé©åã§é¤å»å¯è½ã§ããã¨ã¯ããï¼ããããã¨ã«ãªãã¾ããowning_view
ã好ã¾ããã®ã¯ããããã®åé¡ã¨ç¡ç¸ã§ãããã¨ãçç±ã®ä¸ã¤ã§ãã