Home > Back-end >  How to fix custom allocator compiling error for std::map on windows?
How to fix custom allocator compiling error for std::map on windows?

Time:08-16

I tried one here. Code as following:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <new>
#include <climits>

namespace test {

    template <class T>
    inline T* _allocate(ptrdiff_t size, T*) {
        std::cout << "_allocate called" << std::endl;
        T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
        if (NULL == tmp) {
            std::cerr << "out of memory" << std::endl;
            exit(0);
        }
        return tmp;
    }

    template <class T>
    inline void _deallocate(T* p) {
        ::operator delete(p);
    }

    template <class T1, class T2>
    inline void _construct(T1* p, const T2& value) {
        ::new (p) T1(value);
    }

    template <class T>
    inline void _destroy(T* p) {
        p->~T();
    }

    template <class T>
    class Allocator {
    public:
        typedef T value_type;
        typedef T* pointer;
        typedef const T* const_pointer;
        typedef T& reference;
        typedef const T& const_reference;
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;

        template <class U>
        struct rebind {
            typedef Allocator<U> other;
        };

        pointer allocate(size_type n, const void* hint = 0) { return _allocate((difference_type)n, (pointer)0); }

        void deallocate(pointer p, size_type n) { return _deallocate(p); }

        void construct(pointer p, const T& value) { _construct(p, value); }

        void destroy(pointer p) { _destroy(p); }

        pointer address(reference x) { return (pointer)&x; }

        const_pointer address(const_reference x) { return (const_pointer)&x; }

        size_type max_size() const { return size_type(UINT_MAX / sizeof(T)); }
    };

}  // namespace test

static std::map<void*, uint64_t, std::less<void*>, test::Allocator<std::pair<void* const, uint64_t>>> global_map;

int main()
{
    std::vector<std::string> vec = {
        "Hello", "from", "GCC", "!"
    };
    std::cout << "xxxx " << global_map.size() << std::endl;
}

But it leads to compiling fail on Visual Studio 2019 x86:

Build started...
1>------ Build started: Project: ConsoleApplication1, Configuration: Debug Win32 ------
1>ConsoleApplication1.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30037\include\xtree(1096,27): error C2440: 'static_cast': cannot convert from 'test::Allocator<U>' to 'test::Allocator<U>'
1>        with
1>        [
1>            U=std::_Tree_node<std::pair<void *const ,uint64_t>,void *>
1>        ]
1>        and
1>        [
1>            U=std::_Container_proxy
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30037\include\xtree(1096,27): message : No constructor could take the source type, or constructor overload resolution was ambiguous
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30037\include\xtree(1092): message : while compiling class template member function 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::~_Tree(void) noexcept'
1>        with
1>        [
1>            _Kty=void *,
1>            _Ty=uint64_t,
1>            _Pr=std::less<void *>,
1>            _Alloc=test::Allocator<std::pair<void *const ,uint64_t>>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30037\include\map(348): message : see reference to function template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::~_Tree(void) noexcept' being compiled
1>        with
1>        [
1>            _Kty=void *,
1>            _Ty=uint64_t,
1>            _Pr=std::less<void *>,
1>            _Alloc=test::Allocator<std::pair<void *const ,uint64_t>>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30037\include\map(75): message : see reference to class template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>' being compiled
1>        with
1>        [
1>            _Kty=void *,
1>            _Ty=uint64_t,
1>            _Pr=std::less<void *>,
1>            _Alloc=test::Allocator<std::pair<void *const ,uint64_t>>
1>        ]

How to fix it?

CodePudding user response:

This problem appeard in Visual Studio Debug mode , but solved when switching to Release mode. If it still bothers you, you can report problems to Developer Community.

  • Related