[Boost-bugs] [Boost C++ Libraries] #13644: std::iterator_traits<>::value_type is always non-const for any kind of boost::iterator_facade Iterator

Subject: [Boost-bugs] [Boost C++ Libraries] #13644: std::iterator_traits<>::value_type is always non-const for any kind of boost::iterator_facade Iterator
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2018-07-26 14:32:38


#13644: std::iterator_traits<>::value_type is always non-const for any kind of
boost::iterator_facade Iterator
-----------------------------------------------+---------------------------
 Reporter: Florian Reiser <florian.reiser@…> | Owner:
                                               | jeffrey.hellrung
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: iterator
  Version: Boost 1.67.0 | Severity: Problem
 Keywords: iterator_facade |
-----------------------------------------------+---------------------------
 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.

 You can reproduce this with the following test program:

 {{{
 #!C++
 #include <iterator>
 #include <boost/iterator/iterator_facade.hpp>

 template <typename Value>
 class IteratorTest
         : public boost::iterator_facade<
         IteratorTest<Value>
         , Value
         , boost::forward_traversal_tag
>
 {
 public:
         IteratorTest() {};

 private:
         Value m_value{};
         friend class boost::iterator_core_access;
         template <class> friend class IteratorTest;

         template <typename OtherIteratorType>
         inline bool equal(const IteratorTest<OtherIteratorType>& other)
 const {
                 return true;
         }

         void increment() {
         }

         inline Value& dereference() const noexcept {
                 return m_value;
         }
 };

 template <typename T>
 class DeduceType;

 int main()
 {
         using iterator = IteratorTest<int>;
         using const_iterator = IteratorTest<const int>;

         auto it = iterator();
         auto cit = const_iterator();

         DeduceType<decltype(it)> debug1;
         DeduceType<decltype(cit)> debug2;
         DeduceType<std::iterator_traits<decltype(it)::value_type>> debug3;
         DeduceType<std::iterator_traits<decltype(cit)::value_type>>
 debug4;
 }
 }}}

 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)

 {{{
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(46):
 error C2079: 'debug1' uses undefined class 'DeduceType<iterator>'
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(47):
 error C2079: 'debug2' uses undefined class 'DeduceType<const_iterator>'
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(48):
 error C2079: 'debug3' uses undefined class
 'DeduceType<std::iterator_traits<int>>'
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(49):
 error C2079: 'debug4' uses undefined class
 'DeduceType<std::iterator_traits<int>>'
 }}}

 I've found the reason for this bug in
 boost/iterator/iterator_facade.hpp:120

 {{{
 #!C++

     template <
         class ValueParam
       , class CategoryOrTraversal
       , class Reference
       , class Difference
>
     struct iterator_facade_types
     {
         typedef typename facade_iterator_category<
             CategoryOrTraversal, ValueParam, Reference
>::type iterator_category;

         typedef typename remove_const<ValueParam>::type value_type;

 }}}

 If you change the line
 {{{
 #!C++
 typedef typename remove_const<ValueParam>::type value_type;
 }}}
 to
 {{{
 #!C++
 typedef ValueParam value_type;
 }}}
 the output of my test program is as expected:

 {{{
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(46):
 error C2079: 'debug1' uses undefined class 'DeduceType<iterator>'
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(47):
 error C2079: 'debug2' uses undefined class 'DeduceType<const_iterator>'
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(48):
 error C2079: 'debug3' uses undefined class
 'DeduceType<std::iterator_traits<int>>'
 1>c:\users\florian\source\repos\iterator_facade_const_bug\iterator_facade_const_bug\reproducebug.cpp(49):
 error C2079: 'debug4' uses undefined class
 'DeduceType<std::iterator_traits<const int>>'
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac10/ticket/13644>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2018-07-26 14:38:38 UTC