title: Satisfy std::ranges::range concept
body: <p>In the upcoming C++20 ranges there will be the <a href="https://en.cppreference.com/w/cpp/ranges/range" rel="noreferrer">range concept</a> with the following definition:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>template&lt; class T &gt;
  concept range = __RangeImpl&lt;T&amp;&gt;; // exposition-only definition
  
  template&lt; class T &gt;
  concept __RangeImpl = requires(T&amp;&amp; t) {
    ranges::begin(std::forward&lt;T&gt;(t)); // equality-preserving for forward iterators
    ranges::end  (std::forward&lt;T&gt;(t));
  };
  
  template&lt; class T &gt;
  concept __ForwardingRange = ranges::range&lt;T&gt; &amp;&amp; __RangeImpl&lt;T&gt;;
  </code></pre>
  
  <p>Translating this to plain English I'd say that the only requirement for a type to satisfy the range concept is to be callable with ranges::begin and ranges::end. </p>
  
  <p>However if I create an empty type with just begin and end a static assertion on the range concept fails?</p>
  
  <pre class="lang-cpp prettyprint-override"><code>namespace ranges = std::experimental::ranges;
  
  struct A {
    void begin() {}
    void end() {}
  };
  
  static_assert(ranges::range&lt;A&gt;);
  </code></pre>
  
  <p>What am I missing?</p>