views:

73

answers:

3

Every stl container take an allocator as a parameter:

template < class T, class Allocator = allocator<T> > class vector;

If you write your own class It is possible to use your own allocator. But is it possible to write your own allocator without using templates?

For example, writing this function is not easy if you are not allowed to use templates

 pointer allocate(size_type n, const_pointer = 0) {
    void* p = std::malloc(n * sizeof(T));
    if (!p)
      throw std::bad_alloc();
    return static_cast<pointer>(p);
  }

Because how could you know the size of T?

+2  A: 

Well, if you wrote one that wasn't a template class, it would have to be for a single type only. Just replace T with whichever type you want an allocator for.

Seems like a pointless exercise, since you do in fact have templates available to you to use.

GMan
but I am on a system with a very old gcc-compiler and if I am using templates the memory get messed up, the memory is very limited
Merni
So your compiler works well enough to compile and use STL templated containers, but not well enough to compile and use a templated custom allocator for those containers? That seems unlikely.
Tyler McHenry
@Merni: That's the kind of stuff you should put in your question. What do you mean by the memory gets messed up?
GMan
GMan is right. It sounds like you have a problem that you're trying to solve, and you've become set on using one possible method of solution that you came up with. Instead of asking how to make your chosen method work, you should ask a question about the the underlying problem you have to see if there is a better overall method of solving it.
Tyler McHenry
k, the templates files never get compiled until they are used, so if many cpp file is using the same template they get the their own template data in their object file. So many cpp file have the same data in their obj-file, when the compiler is linking them together, it should see that it is the same code and clean it up so their is only one obj file for that template. The old gcc compilers does not clean up the memory, it only delete the reference to the obj file so only one are used.
Merni
A: 

std::allocator itself is a template class, so if you want to replace it, you need to use a template class.

Now, that being said, it is pretty easy to write an allocator class that forwards allocation requests to another object:

class my_allocator
{
public:
    void *allocate(size_t size) { ... }
}

template <class T>
class my_std_allocator
{
public:
    pointer allocate(size_t count, const void *hint) { return static_cast<pointer>(m_my_allocator->allocate(count*sizeof(T))); }

private:
    my_allocator * const m_my_allocator;

}
MSN
+1  A: 

If you were willing to write an allocator for a single class, you could probably... though it would depend on the container you wish to use it for.

The allocator is required to have this method:

template <class T>
class Allocator
{
public:
  template <class U>
  Allocator(const Allocator<U>& rhs);
};

Why ? If you are using say, a list, then you do not directly allocate space for a T object, rather, the list will have some kind of Node<T> structure which holds one or two pointers to the previous/next nodes.

Therefore, when you pass in a Allocator<T> it will build a Àllocator< Node<T> > from it to do its own allocations.

Now, if you think about the STL containers, the list, set and map have this requirement. I'm not even sure you get away without for vector and deque, and in any case you would not meet the Allocator concept requirements.

Matthieu M.