title: I've written C++ code to treat boost::optional as a range but it doesn't compile
body: <p>I wish to treat boost::optional as a container that can have zero or one elements in it. Logically I should be able to create an iterator to the container and use boost::for_each on it as well. My attempt is below but it fails to compile. I have tried it on GodBolt.</p>
  
  <p><a href="https://godbolt.org/g/z5MFfe" rel="nofollow noreferrer">https://godbolt.org/g/z5MFfe</a></p>
  
  <p>Code below for reference.</p>
  
  <pre><code>#include &lt;boost/optional.hpp&gt;
  #include &lt;boost/range.hpp&gt;
  #include &lt;boost/range/algorithm/for_each.hpp&gt;
  #include &lt;iostream&gt;
  
  namespace boost {
  
      template &lt;typename OT&gt;
          class optional_iterator
          : public boost::iterator_facade&lt;optional_iterator&lt;OT&gt;,
          typename OT::value_type,
          boost::forward_traversal_tag&gt; {
              private:
                  OT m_o;
  
              public:
                  optional_iterator() : m_o(boost::none) {}
                  explicit optional_iterator(OT&amp; o) : m_o(o) {}
  
              private:
                  friend class boost::iterator_core_access;
  
                  void increment() { m_o = boost::none; }
  
                  bool equal(OT&amp; other) const { return this-&gt;m_o == other.m_o; }
  
                  typename OT::value_type&amp; dereference() { return *m_o; }
          };
  
      template &lt;typename T&gt;
          struct optional_iterators {
              typedef optional_iterator&lt;boost::optional&lt;T&gt;&gt; iterator;
              typedef optional_iterator&lt;boost::optional&lt;T&gt; const&gt; const_iterator;
          };
  
      template &lt;class T&gt;
          struct range_mutable_iterator&lt;boost::optional&lt;T&gt;&gt; {
              typedef typename optional_iterators&lt;T&gt;::iterator type;
          };
  
      template &lt;class T&gt;
          struct range_const_iterator&lt;boost::optional&lt;T&gt; const&gt; {
              typedef typename optional_iterators&lt;T const&gt;::const_iterator type;
          };
  
      template &lt;class T&gt;
          inline typename optional_iterators&lt;T&gt;::iterator range_begin(
                  boost::optional&lt;T&gt;&amp; x) {
              return typename optional_iterators&lt;T&gt;::iterator(x);
          }
  
      template &lt;class T&gt;
          inline typename optional_iterators&lt;T&gt;::const_iterator range_begin(
                  boost::optional&lt;T&gt; const&amp; x) {
              return typename optional_iterators&lt;T&gt;::const_iterator(x);
          }
  
      template &lt;class T&gt;
          inline typename optional_iterators&lt;T&gt;::iterator range_end(boost::optional&lt;T&gt;&amp;x) {
              return typename optional_iterators&lt;T&gt;::iterator();
          }
  
      template &lt;class T&gt;
          inline typename optional_iterators&lt;T&gt;::const_iterator range_end(boost::optional&lt;T&gt; const &amp; x) {
              return typename optional_iterators&lt;T&gt;::const_iterator();
          }
  }  // namespace boost
  
  int main() {
      auto a = boost::optional&lt;int&gt;(10);
      auto rb = range_begin(a);
      auto re = range_end(a);
  
     boost::for_each(a, [](int const&amp; i) { std::cout &lt;&lt; i; });
  }
  </code></pre>
  
  <p>I'm fairly sure I've implemented the range and iterator concepts correctly but I get the following compiler errors with gcc 8.1 ( as per godbolt )</p>
  
  <pre><code>#1 with x86-64 gcc 8.1
  In file included from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size_type.hpp:20,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size.hpp:21,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/functions.hpp:20,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range.hpp:18,
  
                   from &lt;source&gt;:3:
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp: In instantiation of 'struct boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt;':
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/has_constraints.hpp:32:62:   required by substitution of 'template&lt;class Model&gt; boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints&lt;Model, (&amp; Model::constraints)&gt;*) [with Model = boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt;]'
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/has_constraints.hpp:42:5:   required from 'const bool boost::concepts::not_satisfied&lt;boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt; &gt;::value'
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/has_constraints.hpp:45:31:   required from 'struct boost::concepts::not_satisfied&lt;boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt; &gt;'
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/mpl/if.hpp:63:11:   required from 'struct boost::mpl::if_&lt;boost::concepts::not_satisfied&lt;boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt; &gt;, boost::concepts::constraint&lt;boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt; &gt;, boost::concepts::requirement&lt;boost::concepts::failed************ boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt;::************&gt; &gt;'
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/concept/detail/general.hpp:51:8:   required from 'struct boost::concepts::requirement_&lt;void (*)(boost::SinglePassRangeConcept&lt;boost::optional&lt;int&gt; &gt;)&gt;'
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size.hpp:62:9:   required from 'UnaryFunction boost::range::for_each(SinglePassRange&amp;, UnaryFunction) [with SinglePassRange = boost::optional&lt;int&gt;; UnaryFunction = main()::&lt;lambda(const int&amp;)&gt;]'
  
  &lt;source&gt;:75:59:   required from here
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp:272:17: error: no type named 'type' in 'struct boost::range_iterator&lt;const boost::optional&lt;int&gt;, void&gt;'
  
           &gt;::type const_iterator;
  
                   ^~~~~~~~~~~~~~
  
  In file included from /opt/compiler-explorer/libs/boost_1_64_0/boost/concept/assert.hpp:35,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/concept_check.hpp:20,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp:19,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size_type.hpp:20,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/size.hpp:21,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range/functions.hpp:20,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/range.hpp:18,
  
                   from &lt;source&gt;:3:
  
  /opt/compiler-explorer/libs/boost_1_64_0/boost/range/concepts.hpp:279:9: error: no type named 'type' in 'struct boost::range_iterator&lt;const boost::optional&lt;int&gt;, void&gt;'
  
           BOOST_RANGE_CONCEPT_ASSERT((
  
           ^~~~~~~~~~~~~~~~~~~~~~~~~~
  
  In file included from /opt/compiler-explorer/gcc-8.1.0/include/c++/8.1.0/algorithm:62,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/core/swap.hpp:25,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/optional/optional.hpp:27,
  
                   from /opt/compiler-explorer/libs/boost_1_64_0/boost/optional.hpp:15,
  
                   from &lt;source&gt;:2:
  
  /opt/compiler-explorer/gcc-8.1.0/include/c++/8.1.0/bits/stl_algo.h:3876:5: error: '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::optional_iterator&lt;boost::optional&lt;int&gt; &gt;; _Funct = main()::&lt;lambda(const int&amp;)&gt;]', declared using local type 'main()::&lt;lambda(const int&amp;)&gt;', is used but never defined [-fpermissive]
  
       for_each(_InputIterator __first, _InputIterator __last, _Function __f)
  
       ^~~~~~~~
  
  /opt/compiler-explorer/gcc-8.1.0/include/c++/8.1.0/bits/stl_algo.h:3876:5: warning: '_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = boost::optional_iterator&lt;boost::optional&lt;int&gt; &gt;; _Funct = main()::&lt;lambda(const int&amp;)&gt;]' used but never defined
  
  Compiler returned: 1
  </code></pre>