help with STL compiler error

M

Mark P

In my code I use something like:

typedef std::list<Edge*,g_mm_Alloc<Edge*> > EdgeList;

and then instantiate some EdgeList objects. Here Edge is a previously
defined class and g_mm_Alloc<T> is a previously defined custom STL
allocator template.

Trying to compile on a Sun system I get the following error:

"/opt/SUNWspro/prod/include/CC/Cstd/./memory", line 488: Error: Using
static_cast to convert from newScan::Edge** to std::list<newScan::Edge*,
g_mm_Alloc<newScan::Edge*>>::__list_node_buffer* not allowed.
"/opt/SUNWspro/prod/include/CC/Cstd/./list", line 132: Where: While
instantiating "std::allocator_interface<g_mm_Alloc<newScan::Edge*>,
std::list<newScan::Edge*,
g_mm_Alloc<newScan::Edge*>>::__list_node_buffer>::allocate(unsigned,
std::list<newScan::Edge*,
g_mm_Alloc<newScan::Edge*>>::__list_node_buffer*)".
"/opt/SUNWspro/prod/include/CC/Cstd/./list", line 132: Where:
Instantiated from non-template code.

Looking for line 488 of ".../memory" I see:

//
// allocator_interface provides all types and typed functions. Memory
// allocated as raw bytes using the class provided by the Allocator
// template parameter. allocator_interface casts appropriately.
//
// Multiple allocator_interface objects can attach to a single
// allocator, thus allowing one allocator to allocate all storage
// for a container, regardless of how many types are involved.
//
// The only real restriction is that pointer and reference are
// hard coded as T* and T&. Partial specialization would
// get around this.
//
template <class Allocator,class T>
class allocator_interface
{
public:
typedef Allocator allocator_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
typedef _TYPENAME _RWSTD_ALLOC_SIZE_TYPE size_type;
typedef _TYPENAME _RWSTD_ALLOC_DIFF_TYPE difference_type;
typedef void* void_pointer;
typedef const void* const_void_pointer;



protected:
allocator_type alloc_;

public:
allocator_interface() _RWSTD_THROW_SPEC_NULL { ; }
allocator_interface(const Allocator& a) _RWSTD_THROW_SPEC_NULL
: alloc_(a) { ; }

pointer address (T& x)
{
return _RWSTD_STATIC_CAST(pointer,&x);
}

size_type max_size () const
{
return alloc_.max_size(sizeof(T));
}

pointer allocate(size_type n, pointer p = 0)
{
return _RWSTD_STATIC_CAST(pointer,alloc_.allocate(n*sizeof(T),p));
// LINE 488 IS IMMEDIATELY ABOVE
}

void deallocate(pointer p, size_type n)
{
alloc_.deallocate(p,n*sizeof(T));
}

inline void construct(pointer p, const T& val);

inline void destroy(T* p);

};

I have no idea what to make of this. It looks like it's trying to cast
a list node to a T*, where it ought to be using some sort of rebind
mechanism. Any help or guidance would be greatly appreciated.

Thanks,
Mark
 
A

abecedarian

Mark said:
In my code I use something like:

typedef std::list<Edge*,g_mm_Alloc<Edge*> > EdgeList;

This is a list of _pointers_ to newScan::Edge objects. Does it really
make sense in your case to use an allocator to allocate pointers (not
pointed-to objects)?
and then instantiate some EdgeList objects. Here Edge is a previously
defined class and g_mm_Alloc<T> is a previously defined custom STL
allocator template.

Trying to compile on a Sun system I get the following error:

"/opt/SUNWspro/prod/include/CC/Cstd/./memory", line 488: Error: Using
static_cast to convert from newScan::Edge** to std::list<newScan::Edge*,
g_mm_Alloc<newScan::Edge*>>::__list_node_buffer* not allowed.

Your RogueWave allocator seemingly doesn't like pointers as objects.
Looking for line 488 of ".../memory" I see:

template <class Allocator,class T>
class allocator_interface
{ [...]

pointer allocate(size_type n, pointer p = 0)
{
return _RWSTD_STATIC_CAST(pointer,alloc_.allocate(n*sizeof(T),p));
// LINE 488 IS IMMEDIATELY ABOVE
}

_RWSTD_STATIC_CAST expands to static_cast (see above) which doesn't
work for pointers. They probably should have used a reinterpret_cast or
a C-style cast here. I'm not entirely sure though ...

[...]
};

I have no idea what to make of this. It looks like it's trying to cast
a list node to a T*, where it ought to be using some sort of rebind
mechanism.

They try to cast a newScan::Edge** to a ...__list_node_buffer*
(probably a void*). The static_cast only works for g_mm_Alloc<Edge>,
Any help or guidance would be greatly appreciated.

Most probably you don't need the g_mm_Alloc<Edge*> thing, just
std::list<Edge*>.

Abe
 
V

Victor Bazarov

This is a list of _pointers_ to newScan::Edge objects. Does it really
make sense in your case to use an allocator to allocate pointers (not
pointed-to objects)?

Why not? He stores pointers to Edge, so he allocates them...

Just a thought.
 
M

Mark P

This is a list of _pointers_ to newScan::Edge objects. Does it really
make sense in your case to use an allocator to allocate pointers (not
pointed-to objects)?

Well my understanding is that a list of Edge* is unlikely to ever
actually allocate space for an Edge* but instead would allocate space
for a list node type, each instance of which would include an Edge* and
other information (prev, next node*, etc.) too. In any case, I don't
see anything non-compliant about this usage.
Most probably you don't need the g_mm_Alloc<Edge*> thing, just
std::list<Edge*>.

But I really do. The memory needs to come from g_mm_Alloc.
 
M

Mark P

Mark said:
In my code I use something like:

typedef std::list<Edge*,g_mm_Alloc<Edge*> > EdgeList;

and then instantiate some EdgeList objects. Here Edge is a previously
defined class and g_mm_Alloc<T> is a previously defined custom STL
allocator template.

Trying to compile on a Sun system I get the following error:

I think I've got this sorted out. This allocator interface wraps an
allocator which has no knowledge of the type for which it allocates, it
just returns void* to allocated memory. To make this work, I simply
modified max_size, allocate, and deallocate within my custom allocator,
such that all of these work in terms of void* and numbers of allocated
words rather than T* and numbers of allocated T objects.

Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top