正如我从cppreference中了解到的,我们需要为自己的自定义分配器定义rebind_alloc
。但我并不真正理解如何让我自己的分配器对我的Map节点也有效。
我做了什么:
template <class T>
class Allocator2
{
public:
using value_type = T;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t ;
using propagate_on_container_move_assignment = std::true_type;
// no idea what I need for rebind_alloc here... ???
template<typename U>
using rebind_alloc = typename std::allocator_traits<Allocator2<T>>::template rebind_alloc<U>;
T* allocate(size_type n, const void* hint = 0)
{
std::cout << "Alloc" << n << std::endl;
return static_cast<T*>(malloc(n*sizeof(T)));
}
void deallocate(T* p, size_type n) { free( p); }
size_type max_size() const { return size_type(std::numeric_limits<unsigned int>::max() / sizeof(T)); }
void construct(T* p, const T& value) { _construct(p, value); }
void destroy(T* p) { _destroy(p); }
};
template<class T, class U>
bool operator==(const Allocator2 <T>&, const Allocator2 <U>&) noexcept { return true; }
template<class T, class U>
bool operator!=(const Allocator2 <T>&, const Allocator2 <U>&) noexcept { return false; }
struct PointCmp {
bool operator()(const int& lhs, const int& rhs ) const
{
return lhs==rhs;
}
};
template < typename T>
void Print( T t)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
using valueType = std::map< int, int>::value_type;
Print( valueType{} );
std::map< int, int , PointCmp, Allocator2< valueType>> m;
for ( unsigned int n = 0; n<1000; n++ )
{
std::cout << "Now set " << n << std::endl;
m[n]=n;
}
}
谁能指出rebind_alloc
的设置?也许也是一个提示,除了看到节点分配给我的Map类型之外,还缺少了什么?
1条答案
按热度按时间pw136qt21#
如何编写自定义分配器?
你刚刚做了。
正如其他人在评论中指出的那样,
rebind_alloc
对于您的分配器来说是不需要的。但你的比较器坏了。当Map通过
! comp(a,b) && ! comp(b,a)
检查等价性时,使用比较器,任何两个元素都被认为是等价的,除非它们相等。这是不对的。也许这就是为什么你认为你的分配器有问题的原因。然而,当所有的数字都相等时,只插入第一个数字而不插入其他数字是正确的。请注意,当您可以使用
std::less<>
时,不需要定义自定义比较器。修复这个问题并添加includes你的allocater就可以正常工作了:
Live Demo