Пользовательский распределитель не может выполнить повторную привязку к другому типу - PullRequest
1 голос
/ 30 сентября 2011

Все

У меня есть код для моего пользовательского распределителя, который написан с намерением стать прокси-сервером для других распределителей, например, чтобы иметь возможность собирать статистику распределения или что-либо еще

 template<int Id, class T, class BaseAlloc> 
class SelfTracingAllocator
    : public BaseAlloc
{
typedef AllocationStatistics<Id> StatsType;

public:
    typedef typename BaseAlloc              base;
    typedef typename base::raw_pointer      raw_pointer;
    typedef typename base::pointer          pointer;
    typedef typename base::const_pointer    const_pointer;
    typedef typename base::reference        reference;
    typedef typename base::const_reference  const_reference;
    typedef typename base::size_type        size_type;
    typedef typename base::value_type       value_type;
    typedef typename base::difference_type  difference_type;

    template<typename Other>
    struct rebind
    {
        typedef SelfTracingAllocator<Id, Other, base> other;
    };

    SelfTracingAllocator()
    {
    }

    SelfTracingAllocator( const SelfTracingAllocator& rhs )
    {
    }

    template<typename Other>
    inline SelfTracingAllocator( const SelfTracingAllocator<Id, Other, base>& rhs )
    {
    }

    ~SelfTracingAllocator()
    {
    }

    template<typename Other>
    inline SelfTracingAllocator& operator=( const SelfTracingAllocator<Id, Other, base>& rhs )
    {
        return (*this);
    }

    inline raw_pointer allocate(size_type count, const void* ptr)
    {
        StatsType::allocated_ += count * sizeof(value_type);
        return base::allocate(count, ptr);
    }

    inline raw_pointer allocate(size_type count)
    {
        StatsType::allocated_ += count * sizeof(value_type);
        return base::allocate(count);
    }

    inline void deallocate( pointer ptr, size_type count )
    {
       StatsType::deallocated_ += count * sizeof(value_type);
       return base::deallocate(ptr, count);
    }

};

template<class T, class U, int Id, class BaseAlloc>
inline bool operator==(const SelfTracingAllocator<Id, T, BaseAlloc>& lhs, const SelfTracingAllocator<Id, U, BaseAlloc>& rhs)
{
    return true;
}

template<class T, class U, int Id, class BaseAlloc>
inline bool operator!=(const SelfTracingAllocator<Id, T, BaseAlloc>& lhs, const SelfTracingAllocator<Id, U, BaseAlloc>& rhs )
{
    return false;
}


template<class T, int Id>
struct my_allocator
{
    typedef SelfTracingAllocator<Id, T, some_allocator<T, MemMgr> > type;
};

Когда я использую этот распределитель как ниже

typedef custom_string<wchar_t, char_traits<wchar_t>, my_allocator<int, 0>::type > string_t;

, я получаю ошибки как ниже

error C2664: 'char_traits<T>::move' : cannot convert parameter 1 from 'int *' to 'wchar_t *'
1>        with
1>        [
1>            T=wchar_t
1>        ]
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>        D:\VRS_Branch\detail/dynamic_buffer.hpp(95) : while compiling class template member function 'void detail::dynamic_buffer<T,Alloc,Traits>::reserve(unsigned int)'
1>        with
1>        [
1>            T=wchar_t,
1>            Alloc=SelfTracingAllocator<0,int,some_allocator<int,MemMgr>>,
1>            Traits=char_traits<wchar_t>
1>        ]

Почему это происходит?У меня есть и структура повторного связывания, и конструктор повторного связывания, так что же не так?

Заранее спасибо, Андрей

1 Ответ

2 голосов
/ 30 сентября 2011

Как насчет использования

template<typename Other>
struct rebind
{
    typedef SelfTracingAllocator<
        Id
        , Other
        , typename base::template rebind<Other>::other
    > other;
};

Прямо сейчас, если у вас есть SelfTracingAllocator<0, int, std::allocator<int> >, то повторное связывание с wchar_t даст SelfTracingAllocator<0, wchar_t, std::allocator<int> >. Это не кажется правильным.

...