title: C++20 Join the inner values of a map with value_type vector of vector using std::ranges
body: <p>Let's go for it:</p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  #include &lt;ranges&gt;
  #include &lt;map&gt;
  
  namespace rv = std::ranges::views;
  
  int main()
  {
      std::map&lt;unsigned, std::vector&lt;std::vector&lt;unsigned&gt;&gt;&gt; m
          = {{0, {{0, 1, 2}, {3, 4, 5}}},
             {1, {{6, 7, 8}, {9, 10, 11}}}};
      
      for (unsigned u : m | rv::values | rv::join | rv::join)
          std::cout &lt;&lt; u &lt;&lt; ' ';
  }
  </code></pre>
  <p>I want to print <code>0 1 2 3 4 5 6 7 8 9 10 11</code>, but it fails to compile using <code>gcc 10.2.0</code>.</p>
  <pre><code>In file included from main.cpp:3:
  /usr/local/include/c++/10.2.0/ranges: In instantiation of 'constexpr const _Derived&amp; std::ranges::view_interface&lt;_Derived&gt;::_M_derived() const [with _Derived = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;]':
  /usr/local/include/c++/10.2.0/ranges:130:73:   required from 'constexpr std::ranges::view_interface&lt;_Derived&gt;::operator bool() const requires requires{std::ranges::__cust::empty(((const std::ranges::view_interface&lt;_Derived&gt;*)this)-&gt;std::ranges::view_interface&lt;_Derived&gt;::_M_derived()());} [with _Derived = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;]'
  /usr/local/include/c++/10.2.0/ranges:2673:56:   required from 'constexpr auto std::ranges::join_view&lt;_Vp&gt;::end() [with _Vp = std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt;]'
  /usr/local/include/c++/10.2.0/bits/range_access.h:419:26:   required from 'constexpr auto std::ranges::__cust_access::_End::operator()(_Tp&amp;&amp;) const [with _Tp = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;&amp;]'
  /usr/local/include/c++/10.2.0/bits/range_access.h:865:13:   required from 'constexpr auto std::ranges::views::__adaptor::operator|(_Range&amp;&amp;, const std::ranges::views::__adaptor::_RangeAdaptorClosure&lt;_Callable&gt;&amp;) [with _Range = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;; _Callable = std::ranges::views::&lt;lambda(_Range&amp;&amp;)&gt;]'
  main.cpp:15:55:   required from here
  /usr/local/include/c++/10.2.0/ranges:112:16: error: static assertion failed
    112 |  static_assert(view&lt;_Derived&gt;);
        |                ^~~~~~~~~~~~~~
  /usr/local/include/c++/10.2.0/ranges:112:16: note: constraints not satisfied
  In file included from /usr/local/include/c++/10.2.0/string:54,
                   from /usr/local/include/c++/10.2.0/bits/locale_classes.h:40,
                   from /usr/local/include/c++/10.2.0/bits/ios_base.h:41,
                   from /usr/local/include/c++/10.2.0/ios:42,
                   from /usr/local/include/c++/10.2.0/ostream:38,
                   from /usr/local/include/c++/10.2.0/iostream:39,
                   from main.cpp:1:
  /usr/local/include/c++/10.2.0/bits/range_access.h:862:13:   required for the satisfaction of 'range&lt;_Tp&gt;' [with _Tp = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt;, std::less&lt;unsigned int&gt;, std::allocator&lt;std::pair&lt;const unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt; &gt; &gt; &gt; &gt;, 1&gt; &gt;]
  /usr/local/include/c++/10.2.0/bits/range_access.h:862:21:   in requirements with '_Tp&amp; __t' [with _Tp = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt;, std::less&lt;unsigned int&gt;, std::allocator&lt;std::pair&lt;const unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt; &gt; &gt; &gt; &gt;, 1&gt; &gt;]
  /usr/local/include/c++/10.2.0/bits/range_access.h:865:13: note: the required expression 'std::ranges::__cust::end(__t)' is invalid
    865 |  ranges::end(__t);
        |  ~~~~~~~~~~~^~~~~
  cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
  In file included from main.cpp:3:
  /usr/local/include/c++/10.2.0/ranges: In instantiation of 'constexpr _Derived&amp; std::ranges::view_interface&lt;_Derived&gt;::_M_derived() [with _Derived = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;]':
  /usr/local/include/c++/10.2.0/ranges:126:67:   required from 'constexpr std::ranges::view_interface&lt;_Derived&gt;::operator bool() requires requires{std::ranges::__cust::empty(((std::ranges::view_interface&lt;_Derived&gt;*)this)-&gt;std::ranges::view_interface&lt;_Derived&gt;::_M_derived()());} [with _Derived = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;]'
  /usr/local/include/c++/10.2.0/ranges:2673:56:   required from 'constexpr auto std::ranges::join_view&lt;_Vp&gt;::end() [with _Vp = std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt;]'
  /usr/local/include/c++/10.2.0/bits/range_access.h:419:26:   required from 'constexpr auto std::ranges::__cust_access::_End::operator()(_Tp&amp;&amp;) const [with _Tp = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;&amp;]'
  /usr/local/include/c++/10.2.0/bits/range_access.h:865:13:   required from 'constexpr auto std::ranges::views::__adaptor::operator|(_Range&amp;&amp;, const std::ranges::views::__adaptor::_RangeAdaptorClosure&lt;_Callable&gt;&amp;) [with _Range = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int&gt; &gt; &gt; &gt;, 1&gt; &gt;; _Callable = std::ranges::views::&lt;lambda(_Range&amp;&amp;)&gt;]'
  main.cpp:15:55:   required from here
  /usr/local/include/c++/10.2.0/ranges:105:16: error: static assertion failed
    105 |  static_assert(view&lt;_Derived&gt;);
        |                ^~~~~~~~~~~~~~
  /usr/local/include/c++/10.2.0/ranges:105:16: note: constraints not satisfied
  In file included from /usr/local/include/c++/10.2.0/string:54,
                   from /usr/local/include/c++/10.2.0/bits/locale_classes.h:40,
                   from /usr/local/include/c++/10.2.0/bits/ios_base.h:41,
                   from /usr/local/include/c++/10.2.0/ios:42,
                   from /usr/local/include/c++/10.2.0/ostream:38,
                   from /usr/local/include/c++/10.2.0/iostream:39,
                   from main.cpp:1:
  /usr/local/include/c++/10.2.0/bits/range_access.h:862:13:   required for the satisfaction of 'range&lt;_Tp&gt;' [with _Tp = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt;, std::less&lt;unsigned int&gt;, std::allocator&lt;std::pair&lt;const unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt; &gt; &gt; &gt; &gt;, 1&gt; &gt;]
  /usr/local/include/c++/10.2.0/bits/range_access.h:862:21:   in requirements with '_Tp&amp; __t' [with _Tp = std::ranges::join_view&lt;std::ranges::elements_view&lt;std::ranges::ref_view&lt;std::map&lt;unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt;, std::less&lt;unsigned int&gt;, std::allocator&lt;std::pair&lt;const unsigned int, std::vector&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;, std::allocator&lt;std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt; &gt; &gt; &gt; &gt; &gt; &gt;, 1&gt; &gt;]
  /usr/local/include/c++/10.2.0/bits/range_access.h:865:13: note: the required expression 'std::ranges::__cust::end(__t)' is invalid
    865 |  ranges::end(__t);
        |  ~~~~~~~~~~~^~~~~
  main.cpp: In function 'int main()':
  main.cpp:15:55: error: cannot convert 'std::vector&lt;unsigned int&gt;' to 'unsigned int' in initialization
     15 |     for (unsigned u : m | rv::values | rv::join | rv::join)
  </code></pre>