Opened 4 years ago
#13644 new Bugs
std::iterator_traits<>::value_type is always non-const for any kind of boost::iterator_facade Iterator
Reported by: | Owned by: | jeffrey.hellrung | |
---|---|---|---|
Milestone: | To Be Determined | Component: | iterator |
Version: | Boost 1.67.0 | Severity: | Problem |
Keywords: | iterator_facade | Cc: |
Description
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:
#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
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
typedef typename remove_const<ValueParam>::type value_type;
to
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>>'