libc++ std::list implementation mistake?
Mar 29, 2014 at 2:24pm UTC
Considering:
http://llvm.org/svn/llvm-project/libcxx/branches/release_34/include/list
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
_LIBCPP_INLINE_VISIBILITY
pointer operator ->() const
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this ),
"Attempted to dereference a non-dereferenceable list::iterator" );
#endif
return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
}
// ...
_LIBCPP_INLINE_VISIBILITY
pointer operator ->() const
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this ),
"Attempted to dereference a non-dereferenceable list::iterator" );
#endif
return pointer_traits<pointer>::pointer_to(__ptr_->__value_);
}
The first
operator->() is from
__list_iterator .
The second
operator->() is from
__list_const_iterator .
Why doesn't the second overload return
const_pointer ?
And for this purpose, why does it not use code similar to:
return pointer_traits<const_pointer>::pointer_to(__ptr_->__value_);
Something similar is happening for
operator*() not returning
const_reference .
Is this on purpose, and if yes, what is achieved?
Thanks.
Mar 29, 2014 at 2:33pm UTC
You should ask this on Stackoverflow. You will get much better response there
Might have to do with this:
1 2 3 4 5 6 7 8 9 10
class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator {
...
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind<const value_type>
#else
rebind<const value_type>::other
#endif
pointer;
...
}
1 2 3 4 5 6 7 8 9 10
class _LIBCPP_TYPE_VIS_ONLY __list_iterator {
...
#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
rebind<value_type>
#else
rebind<value_type>::other
#endif
pointer;
...
}
Also
operator *() returns const reference because:
1 2 3 4 5
class _LIBCPP_TYPE_VIS_ONLY __list_const_iterator {
...
typedef const value_type& reference;
...
}
To test it works, try it with clang which is an LLVM compiler:
http://coliru.stacked-crooked.com/a/29c63ec48e114a6a
Last edited on Mar 29, 2014 at 3:28pm UTC
Mar 29, 2014 at 4:31pm UTC
> Why doesn't the second overload return const_pointer?
std::list<T,A>::iterator::pointer
is
T*
std::list<T,A>::const_iterator::pointer
is
const T*
pointer operator ->() const
in the iterator class returns the
pointer
defined by the iterator.
The name is the same in both classes, but the types are different.
1 2 3 4 5 6 7 8 9 10 11 12 13
#include <iostream>
#include <list>
#include <typeinfo>
void foo( int * ) { std::cout << "pointer to int\n" ; }
void foo( const int * ) { std::cout << "pointer to const int\n" ; }
int main()
{
foo( std::list<int >::iterator::pointer{} ) ; // pointer to int
foo( std::list<int >::const_iterator::pointer{} ) ; // pointer to const int
}
http://coliru.stacked-crooked.com/a/e5c74a71febbc92f
Topic archived. No new replies allowed.