https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124787

            Bug ID: 124787
           Summary: cannot use two times inherited std::allocator for
                    std::deque
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pali at kernel dot org
  Target Milestone: ---

std::vector and std::list can use allocator which is two-times inherited from
std::allocator. But std::deque for the same construction is throwing a compile
error related to rebind_alloc.

Code:

    #include <list>
    #include <deque>
    #include <vector>

    template<class T>
    struct my_allocator1 : std::allocator<T>
    {
        template<typename U>
        struct rebind
        {
            typedef my_allocator1<U> other;
        };
    };

    template<class T>
    struct my_allocator2 : my_allocator1<T>
    {
        template<typename U>
        struct rebind
        {
            typedef my_allocator2<U> other;
        };
    };

    int main()
    {
        std::vector<int, my_allocator1<int>> v1;
        std::vector<int, my_allocator2<int>> v2;
        std::list<int, my_allocator1<int>> l1;
        std::list<int, my_allocator2<int>> l2;
        std::deque<int, my_allocator1<int>> d1;
        std::deque<int, my_allocator2<int>> d2;
    }


Compile error (g++ test.cpp -std=c++20):

    In file included from /usr/include/c++/15.2.0/deque:68,
                     from test.cpp:2:
    /usr/include/c++/15.2.0/bits/stl_deque.h: In instantiation of
'std::_Deque_base<_Tp, _Alloc>::_Map_alloc_type std::_Deque_base<_Tp,
_Alloc>::_M_get_map_allocator() const [with _Tp = int; _Alloc =
my_allocator2<int>; _Map_alloc_type = std::allocator_traits<my_allocator2<int>
>::rebind_alloc<int*>]':
    /usr/include/c++/15.2.0/bits/stl_deque.h:606:32:   required from 'void
std::_Deque_base<_Tp, _Alloc>::_M_deallocate_map(_Map_pointer, std::size_t)
[with _Tp = int; _Alloc = my_allocator2<int>; _Map_pointer = int**; std::size_t
= long unsigned int]'
      606 |         _Map_alloc_type __map_alloc = _M_get_map_allocator();
          |                                       ^~~~~~~~~~~~~~~~~~~~
    /usr/include/c++/15.2.0/bits/stl_deque.h:627:4:   required from
'std::_Deque_base<_Tp, _Alloc>::~_Deque_base() [with _Tp = int; _Alloc =
my_allocator2<int>]'
      627 |           _M_deallocate_map(this->_M_impl._M_map,
this->_M_impl._M_map_size);
          |           ^~~~~~~~~~~~~~~~~
    /usr/include/c++/15.2.0/bits/stl_deque.h:858:7:   required from here
      858 |       deque() = default;
          |       ^~~~~
    /usr/include/c++/15.2.0/bits/stl_deque.h:580:16: error: could not convert
'((const std::_Deque_base<int, my_allocator2<int>
>*)this)->std::_Deque_base<int, my_allocator2<int> >::_M_get_Tp_allocator()'
from 'const std::_Deque_base<int, my_allocator2<int> >::_Tp_alloc_type' {aka
'std::allocator_traits<my_allocator2<int> >::rebind_alloc<int>'} to
'my_allocator1<int*>'
      580 |       { return _Map_alloc_type(_M_get_Tp_allocator()); }
          |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          |                |
          |                const std::_Deque_base<int, my_allocator2<int>
>::_Tp_alloc_type {aka std::allocator_traits<my_allocator2<int>
>::rebind_alloc<int>}


When the line for d2 declaration is commented then the code is compiled fine
without any error. So it seems that the gcc's libstdc++ std::deque is using
std::allocator differently than std::vector and std::list, which do not have
this problem.

Reply via email to