Boost C++ Libraries: Ticket #12071: Using iterator_facade with range-v3 fails to compile https://svn.boost.org/trac10/ticket/12071 <p> The fact that <code>postfix_increment_proxy</code> is not <code>DefaultConstructible</code> and doesn't have a nested public <code>value_type</code> makes iterators unusable with range-v3, which check the concepts. </p> <p> Example: </p> <pre class="wiki">#include "boost/iterator/iterator_facade.hpp" #include "range/v3/utility/iterator.hpp" template &lt;class V, class Category&gt; class TestIter : public boost::iterator_facade&lt;TestIter&lt;V, Category&gt;, V, Category, V&gt; { public: using typename boost::iterator_facade&lt;TestIter&lt;V, Category&gt;, V, Category, V&gt;::difference_type; TestIter() : v_() {} explicit TestIter(V v) : v_(v) {} private: friend class boost::iterator_core_access; V dereference() const { return v_; } bool equal(const TestIter&amp; other) const { return v_ == other.v_; } void increment() { ++v_; } void decrement() { --v_; } void advance(difference_type n) { v_ += n; } difference_type distance_to(const TestIter&amp; other) const { return other.v_ - v_; } V v_; }; using InIter = TestIter&lt;int, std::input_iterator_tag&gt;; static_assert(ranges::InputIterator&lt;InIter&gt;(), ""); void f(InIter x) { static_assert(ranges::Readable&lt;decltype(x++)&gt;(), ""); static_assert(ranges::DefaultConstructible&lt;decltype(x++)&gt;(), ""); } </pre><p> I think <code>static_assert(ranges::InputIterator&lt;InIter&gt;(), "")</code> fails, because the two static_asserts in <code>f()</code> fail. </p> <p> From what I've learned here: <a class="ext-link" href="https://github.com/ericniebler/range-v3/issues/304"><span class="icon">​</span>https://github.com/ericniebler/range-v3/issues/304</a> it seems a good idea to fix <code>postfix_increment_proxy</code> to conform to these requirements. Ditto <code>writable_postfix_increment_proxy</code>. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12071 Trac 1.4.3 Krzysztof Czaiński <1czajnik@…> Wed, 23 Mar 2016 14:58:22 GMT <link>https://svn.boost.org/trac10/ticket/12071#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12071#comment:1</guid> <description> <p> Here's a simple fix, which works as long as the value type is <a class="missing wiki">DefaultConstructible</a>: </p> <pre class="wiki">--- boost/boost/iterator/iterator_facade.hpp +++ boost/boost/iterator/iterator_facade.hpp @@ -152,8 +152,9 @@ template &lt;class Iterator&gt; class postfix_increment_proxy { + public: typedef typename iterator_value&lt;Iterator&gt;::type value_type; - public: + postfix_increment_proxy() {} explicit postfix_increment_proxy(Iterator const&amp; x) : stored_value(*x) {} @@ -178,8 +179,9 @@ template &lt;class Iterator&gt; class writable_postfix_increment_proxy { + public: typedef typename iterator_value&lt;Iterator&gt;::type value_type; - public: + writable_postfix_increment_proxy() {} explicit writable_postfix_increment_proxy(Iterator const&amp; x) : stored_value(*x) , stored_iterator(x) </pre><p> To work around values which aren't <a class="missing wiki">DefaultConstructible</a>, it might be necessary to wrap the <code>stored_value</code> in <code>optional</code>, but the above simple fix will work for majority of cases. </p> </description> <category>Ticket</category> </item> <item> <author>Krzysztof Czaiński <1czajnik@…></author> <pubDate>Wed, 20 Apr 2016 15:21:25 GMT</pubDate> <title>summary changed https://svn.boost.org/trac10/ticket/12071#comment:2 https://svn.boost.org/trac10/ticket/12071#comment:2 <ul> <li><strong>summary</strong> <span class="trac-field-old">postfix_increment_proxy is not DefaultConstructible and doesn't have a nested public value_type</span> → <span class="trac-field-new">Using iterator_facade with range-v3 fails to compile</span> </li> </ul> <p> Maybe a high-level example will be helpful: </p> <pre class="wiki">#include &lt;iostream&gt; #include "third_party/boost/allowed/iterator/iterator_facade.hpp" #include "third_party/range_v3/include/range/v3/algorithm/copy.hpp" #include "third_party/range_v3/include/range/v3/iterator_range.hpp" #include "third_party/range_v3/include/range/v3/utility/iterator.hpp" template &lt;class V, class Category&gt; class TestIter : public boost::iterator_facade&lt;TestIter&lt;V, Category&gt;, V, Category, V&gt; { public: using typename boost::iterator_facade&lt;TestIter&lt;V, Category&gt;, V, Category, V&gt;::difference_type; TestIter() : v_() {} explicit TestIter(V v) : v_(v) {} private: friend class boost::iterator_core_access; V dereference() const { return v_; } bool equal(const TestIter&amp; other) const { return v_ == other.v_; } void increment() { ++v_; } void decrement() { --v_; } void advance(difference_type n) { v_ += n; } difference_type distance_to(const TestIter&amp; other) const { return other.v_ - v_; } V v_; }; using InIter = TestIter&lt;int, std::input_iterator_tag&gt;; template &lt;class R&gt; void print(R&amp;&amp; r) { ranges::copy(std::forward&lt;R&gt;(r), ranges::ostream_iterator&lt;&gt;(std::cout, ", ")); std::cout &lt;&lt; "\n"; } int main() { print(ranges::make_iterator_range(InIter(1), InIter(10))); } </pre> Ticket