Boost C++ Libraries: Ticket #13644: std::iterator_traits<>::value_type is always non-const for any kind of boost::iterator_facade Iterator https://svn.boost.org/trac10/ticket/13644 <p> I've found a bug in boost::iterator_facade. If you define your own iterator by using the facade and you try to deduce the value_type of the iterator by using std::iterator_traits, the type is always non-const independently of the iterator value type declaration. </p> <p> You can reproduce this with the following test program: </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;iterator&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/iterator/iterator_facade.hpp&gt;</span><span class="cp"></span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Value</span><span class="o">&gt;</span> <span class="k">class</span> <span class="nc">IteratorTest</span> <span class="o">:</span> <span class="k">public</span> <span class="n">boost</span><span class="o">::</span><span class="n">iterator_facade</span><span class="o">&lt;</span> <span class="n">IteratorTest</span><span class="o">&lt;</span><span class="n">Value</span><span class="o">&gt;</span> <span class="p">,</span> <span class="n">Value</span> <span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">forward_traversal_tag</span> <span class="o">&gt;</span> <span class="p">{</span> <span class="k">public</span><span class="o">:</span> <span class="n">IteratorTest</span><span class="p">()</span> <span class="p">{};</span> <span class="k">private</span><span class="o">:</span> <span class="n">Value</span> <span class="n">m_value</span><span class="p">{};</span> <span class="k">friend</span> <span class="k">class</span> <span class="nc">boost</span><span class="o">::</span><span class="n">iterator_core_access</span><span class="p">;</span> <span class="k">template</span> <span class="o">&lt;</span><span class="n">class</span><span class="o">&gt;</span> <span class="k">friend</span> <span class="k">class</span> <span class="nc">IteratorTest</span><span class="p">;</span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">OtherIteratorType</span><span class="o">&gt;</span> <span class="kr">inline</span> <span class="kt">bool</span> <span class="n">equal</span><span class="p">(</span><span class="k">const</span> <span class="n">IteratorTest</span><span class="o">&lt;</span><span class="n">OtherIteratorType</span><span class="o">&gt;&amp;</span> <span class="n">other</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">increment</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span> <span class="kr">inline</span> <span class="n">Value</span><span class="o">&amp;</span> <span class="n">dereference</span><span class="p">()</span> <span class="k">const</span> <span class="k">noexcept</span> <span class="p">{</span> <span class="k">return</span> <span class="n">m_value</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span> <span class="k">class</span> <span class="nc">DeduceType</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="k">using</span> <span class="n">iterator</span> <span class="o">=</span> <span class="n">IteratorTest</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">using</span> <span class="n">const_iterator</span> <span class="o">=</span> <span class="n">IteratorTest</span><span class="o">&lt;</span><span class="k">const</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">auto</span> <span class="n">it</span> <span class="o">=</span> <span class="n">iterator</span><span class="p">();</span> <span class="k">auto</span> <span class="n">cit</span> <span class="o">=</span> <span class="n">const_iterator</span><span class="p">();</span> <span class="n">DeduceType</span><span class="o">&lt;</span><span class="k">decltype</span><span class="p">(</span><span class="n">it</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">debug1</span><span class="p">;</span> <span class="n">DeduceType</span><span class="o">&lt;</span><span class="k">decltype</span><span class="p">(</span><span class="n">cit</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">debug2</span><span class="p">;</span> <span class="n">DeduceType</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o">&lt;</span><span class="k">decltype</span><span class="p">(</span><span class="n">it</span><span class="p">)</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;&gt;</span> <span class="n">debug3</span><span class="p">;</span> <span class="n">DeduceType</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">iterator_traits</span><span class="o">&lt;</span><span class="k">decltype</span><span class="p">(</span><span class="n">cit</span><span class="p">)</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;&gt;</span> <span class="n">debug4</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> With my VS2017 compiler, I receive the following compiler output (I've omitted the implementation of DeduceType to force the compiler to tell me the type; so the compiler error here is not an Error) </p> <pre class="wiki">1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(46): error C2079: 'debug1' uses undefined class 'DeduceType&lt;iterator&gt;' 1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(47): error C2079: 'debug2' uses undefined class 'DeduceType&lt;const_iterator&gt;' 1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(48): error C2079: 'debug3' uses undefined class 'DeduceType&lt;std::iterator_traits&lt;int&gt;&gt;' 1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(49): error C2079: 'debug4' uses undefined class 'DeduceType&lt;std::iterator_traits&lt;int&gt;&gt;' </pre><p> I've found the reason for this bug in boost/iterator/iterator_facade.hpp:120 </p> <div class="wiki-code"><div class="code"><pre> <span class="k">template</span> <span class="o">&lt;</span> <span class="k">class</span> <span class="nc">ValueParam</span> <span class="p">,</span> <span class="k">class</span> <span class="nc">CategoryOrTraversal</span> <span class="p">,</span> <span class="k">class</span> <span class="nc">Reference</span> <span class="p">,</span> <span class="k">class</span> <span class="nc">Difference</span> <span class="o">&gt;</span> <span class="k">struct</span> <span class="n">iterator_facade_types</span> <span class="p">{</span> <span class="k">typedef</span> <span class="k">typename</span> <span class="n">facade_iterator_category</span><span class="o">&lt;</span> <span class="n">CategoryOrTraversal</span><span class="p">,</span> <span class="n">ValueParam</span><span class="p">,</span> <span class="n">Reference</span> <span class="o">&gt;::</span><span class="n">type</span> <span class="n">iterator_category</span><span class="p">;</span> <span class="k">typedef</span> <span class="k">typename</span> <span class="n">remove_const</span><span class="o">&lt;</span><span class="n">ValueParam</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">value_type</span><span class="p">;</span> </pre></div></div><p> If you change the line </p> <div class="wiki-code"><div class="code"><pre><span class="k">typedef</span> <span class="k">typename</span> <span class="n">remove_const</span><span class="o">&lt;</span><span class="n">ValueParam</span><span class="o">&gt;::</span><span class="n">type</span> <span class="n">value_type</span><span class="p">;</span> </pre></div></div><p> to </p> <div class="wiki-code"><div class="code"><pre><span class="k">typedef</span> <span class="n">ValueParam</span> <span class="n">value_type</span><span class="p">;</span> </pre></div></div><p> the output of my test program is as expected: </p> <pre class="wiki">1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(46): error C2079: 'debug1' uses undefined class 'DeduceType&lt;iterator&gt;' 1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(47): error C2079: 'debug2' uses undefined class 'DeduceType&lt;const_iterator&gt;' 1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(48): error C2079: 'debug3' uses undefined class 'DeduceType&lt;std::iterator_traits&lt;int&gt;&gt;' 1&gt;c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(49): error C2079: 'debug4' uses undefined class 'DeduceType&lt;std::iterator_traits&lt;const int&gt;&gt;' </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13644 Trac 1.4.3