libc++ std::list implementation mistake?

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.
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
> 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.