By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,995 Members | 1,268 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,995 IT Pros & Developers. It's quick & easy.

Help with STL allocators

P: n/a
Hi,

I have a written a custom allocator for STL, on the lines of default
allocator as follows :

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

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

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <class U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}
size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void destroy(char* ){}
void destroy(void* ){}
void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

//template <class T> pool pool_allocator<T>::mem_;

template <class T, class U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <class T, class U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

I do a simple thing like : map<int, float, less<int>,
pool_allocator<pair<int, float> > > m;
I try to build it on HPUX using aCC (aCC: HP ANSI C++ B3910B A.03.39
). But unfortunately, I am facing following errors :

Error 874: "/opt/aCC/include/memory", line 529 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef T& reference;
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 530 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef const T& const_reference;
^^^^^^^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
I am not very good at this ... any reasons why this could be happening
?

~mar00ned
Jul 22 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"mar00ned" <ro**********@gmail.com> wrote in message
news:84**************************@posting.google.c om...
Hi,

I have a written a custom allocator for STL, on the lines of default
allocator as follows :

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

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

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <class U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}
size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void destroy(char* ){}
void destroy(void* ){}
void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

//template <class T> pool pool_allocator<T>::mem_;

template <class T, class U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <class T, class U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

I do a simple thing like : map<int, float, less<int>,
pool_allocator<pair<int, float> > > m;
I try to build it on HPUX using aCC (aCC: HP ANSI C++ B3910B A.03.39
). But unfortunately, I am facing following errors :

Error 874: "/opt/aCC/include/memory", line 529 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef T& reference;
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 530 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef const T& const_reference;
^^^^^^^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
I am not very good at this ... any reasons why this could be happening
?


You need to create a specialised void allocator. Since you cannot allocate
void objects this allocator is very simple.

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;

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

};

Something like that anyway. The particular error you were getting were
because the compiler was trying to substitute void for T in your
unspecialised template and coming up with code like this

typedef void& reference;

which is illegal because you cannot have a void reference.

john
Jul 22 '05 #2

P: n/a
My allocator looks like this now :

template <class T> class pool_allocator;
template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <class U>
struct rebind { typedef pool_allocator<U> other; };

};

template <class T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
....

but unfortunately the error havent stopped.

Thanks and regards,
~mar00ned

"John Harrison" <jo*************@hotmail.com> wrote in message
news:2r*************@uni-berlin.de...

"mar00ned" <ro**********@gmail.com> wrote in message
news:84**************************@posting.google.c om...
Hi,

I have a written a custom allocator for STL, on the lines of default
allocator as follows :

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

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

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <class U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}
size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void destroy(char* ){}
void destroy(void* ){}
void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

//template <class T> pool pool_allocator<T>::mem_;

template <class T, class U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <class T, class U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

I do a simple thing like : map<int, float, less<int>,
pool_allocator<pair<int, float> > > m;
I try to build it on HPUX using aCC (aCC: HP ANSI C++ B3910B A.03.39
). But unfortunately, I am facing following errors :

Error 874: "/opt/aCC/include/memory", line 529 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef T& reference;
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 530 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
typedef const T& const_reference;
^^^^^^^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 546 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
pointer address (T& x)
^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
^^^^^^^^^
Error 874: "/opt/aCC/include/memory", line 595 # A non-void type is
required for specialization instead of 'void' since the template
creates a reference to that type.
allocator_interface<Allocator,T>::construct(pointe r p, const T&
val)
I am not very good at this ... any reasons why this could be happening
?


You need to create a specialised void allocator. Since you cannot allocate
void objects this allocator is very simple.

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;

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

};

Something like that anyway. The particular error you were getting were
because the compiler was trying to substitute void for T in your
unspecialised template and coming up with code like this

typedef void& reference;

which is illegal because you cannot have a void reference.

john

Jul 22 '05 #3

P: n/a

"Rohit Mattoo" <ji****@gmail.com> wrote in message
news:10***************@cswreg.cos.agilent.com...
My allocator looks like this now :

template <class T> class pool_allocator;
template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <class U>
struct rebind { typedef pool_allocator<U> other; };

};

template <class T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
....

but unfortunately the error havent stopped.

Thanks and regards,
~mar00ned


I think you should put your specialised template after your generic one, not
before.

john
Jul 22 '05 #4

P: n/a
Unfortunately this hasnt worked either :

#ifndef POOL_ALLOCATOR_H_INCLUDED_GF
#define POOL_ALLOCATOR_H_INCLUDED_GF

#include <map>
#include "pool.h"
template <typename T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

template <typename U>
struct rebind { typedef pool_allocator<U> other; };

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <typename U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}
size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
{
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void destroy(char* ){}
void destroy(void* ){}
void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <typename U>
struct rebind { typedef pool_allocator<U> other; };
pool_allocator() {}
~pool_allocator() {}
};

template <typename T> pool pool_allocator<T>::mem_;

template <typename T, typename U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <typename T, typename U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

template<typename Key, typename Value, class Traits = less<Key> >
struct PooledMap
{
typedef map<Key, Value, Traits,pool_allocator<pair<Key, Value> > > Type;
};
#endif


"John Harrison" <jo*************@hotmail.com> wrote in message
news:2r*************@uni-berlin.de...

"Rohit Mattoo" <ji****@gmail.com> wrote in message
news:10***************@cswreg.cos.agilent.com...
My allocator looks like this now :

template <class T> class pool_allocator;
template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <class U>
struct rebind { typedef pool_allocator<U> other; };

};

template <class T>
class pool_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
....

but unfortunately the error havent stopped.

Thanks and regards,
~mar00ned
I think you should put your specialised template after your generic one,

not before.

john

Jul 22 '05 #5

P: n/a
On Fri, 24 Sep 2004 14:06:41 +0100, "Rohit Mattoo" <ji****@gmail.com>
wrote:
template<typename Key, typename Value, class Traits = less<Key> >
struct PooledMap
{
typedef map<Key, Value, Traits,pool_allocator<pair<Key, Value> > > Type;


That should be:
typedef map<Key, Value,
Traits, pool_allocator<pair<const Key, Value> > > Type;

What's the error you're getting now?

Tom
Jul 22 '05 #6

P: n/a

"Rohit Mattoo" <ji****@gmail.com> wrote in message
news:10***************@cswreg.cos.agilent.com...
Unfortunately this hasnt worked either :

I took this code (I had to fake the pool object) and it compiled fine. The
only change I had to make from your code was to remove the void* and char*
versions of destroy (I don't know why you put them there).

Maybe you have a problem with your compiler, your error messages indicate
that it is ignoring the void specialised version of pool_allocator.
#include <map>

class pool
{
public:
void* allocate(std::size_t);
void deallocate(void*, std::size_t);
};

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

template <typename U>
struct rebind { typedef pool_allocator<U> other; };

pointer address(reference x) const {return &x;}
const_pointer address(const_reference x) const {return &x;}

pool_allocator(){}
pool_allocator(const pool_allocator&) {}
template <typename U>
pool_allocator (const pool_allocator<U>&) {}
~pool_allocator(){}
size_type max_size() const throw() {return size_t(-1) /
sizeof(value_type);}

pointer allocate(size_type size, const void* hint = 0)
{
return static_cast<pointer>(mem_.allocate(size*sizeof(T)) );
}

void construct(pointer p, const T& val)
{
new(static_cast<void*>(p)) T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p)) T();
}

void destroy(pointer p){p->~T();}
void deallocate(pointer p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(void *p, size_type n)
{
mem_.deallocate(p, n);
}
void deallocate(pointer p)
{
mem_.deallocate(p);
}
void deallocate(void *p)
{
mem_.deallocate(p);
}

static void dump(){
mem_.dump();
}

private:

static pool mem_;
};

template <>
class pool_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
template <typename U>
struct rebind { typedef pool_allocator<U> other; };
pool_allocator() {}
~pool_allocator() {}
};

template <typename T> pool pool_allocator<T>::mem_;

template <typename T, typename U>
inline bool operator==(const pool_allocator<T>&, const
pool_allocator<U>){return true;}

template <typename T, typename U>
inline bool operator!=(const pool_allocator<T>&, const
pool_allocator<U>){return false;}

std::map<int, float, std::less<int>, pool_allocator<std::pair<int, float> > m;

int main()
{
m[2] = 3.0;
}
John
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.