The class std::allocator<...> does not have virtual functions. Therefore, this is clearly a poor candidate for providing derivative functionality. Although some classes or class templates are still reasonable base classes, even without a virtual destructor and any other virtual function, they tend to be either just tag types or use a curiously repeating template pattern .
Highlighters are not designed for this setting, i.e. std::allocator<T> not for the base class. If you try to use it as such, your logic can be easily removed. The approach used to easily configure dispensers is to rely on std::allocator_traits<A> to provide various operations that your dispenser prefers not to provide explicitly using the default implementation based on a relatively small number of operations.
The main problem getting std::allocator<T> is that it can hide a problem with the rebind element, for example, an element that is omitted or spelled. The following is an example that should print my_allocator::allocate() twice, but not because of a typo. I think my_allocator<T> except for the typo of the full distributor even without inheritance from std::allocator<T> , i.e. Unnecessary inheritance only contributes to the potential concealment of errors. You may also receive an error message, for example, if the allocate() or deallocate() function allocate() not work correctly.
#include <memory> #include <iostream> template <typename T> struct my_allocator : std::allocator<T> { my_allocator() {} template <typename U> my_allocator(my_allocator<U> const&) {} typedef T value_type; template <typename U> struct rebimd { typedef my_allocator<U> other; }; T* allocate(size_t n) { std::cout << "my_allocator::allocate()\n"; return static_cast<T*>(operator new(n*sizeof(T))); } void deallocate(T* p, size_t) { operator delete(p); } }; template <typename A> void f(A a) { typedef std::allocator_traits<A> traits; typedef typename traits::value_type value_type; typedef typename traits::pointer pointer; pointer p = traits::allocate(a, sizeof(value_type)); traits::deallocate(a, p, sizeof(value_type)); typedef typename traits::template rebind_alloc<int> other; typedef std::allocator_traits<other> otraits; typedef typename otraits::value_type ovalue_type; typedef typename otraits::pointer opointer; other o(a); opointer op = otraits::allocate(o, sizeof(ovalue_type)); otraits::deallocate(o, op, sizeof(ovalue_type)); } int main() { f(my_allocator<int>()); }
Dietmar KΓΌhl Jan 13 '14 at 0:12 2014-01-13 00:12
source share