Template Inheritance and Instantiation -- A Simpler Hashtable Iterator
Chad Gatesman
chadg@redrose.net
Fri Sep 4 06:42:00 GMT 1998
I am trying to develop a simpler hashtable iterator. By simpler, I mean
one that will dereference to just the Value instead of pair<Key,Value>.
At first I tryed to write a wrapper around the template iterator, but
ran into some problems. I am now implementing it by inheriting
__hashtable_const_iterator defined in stl_hashtable.h.
I was able to implement it, and it compiled fine with egcs-1.0.3. Here
is my implementation:
#include <hash_map>
// CSimpleHashIterator
// Acts just like a hashtable iterator,
// but only dereferences the value
// instead of pair<Key,Value>
template <class Value, class Key, class HashFcn = hash<Key>,
class ExtractKey = select1st<pair<const Key, Value> >,
class EqualKey = equal_to<Key>, class Alloc = alloc>
struct CSimpleHashIterator
: public __hashtable_iterator<pair<const Key, Value>, Key, HashFcn,
ExtractKey, EqualKey, Alloc>
{
CSimpleHashIterator(void)
: __hashtable_iterator<pair<const Key, Value>, Key, HashFcn,
ExtractKey, EqualKey, Alloc>() {}
CSimpleHashIterator(node* n, hashtable* tab)
: __hashtable_iterator<pair<const Key, Value>, Key, HashFcn,
ExtractKey, EqualKey, Alloc>(n, tab) {}
CSimpleHashIterator(const __hashtable_iterator<pair<const Key,Value>,
Key, HashFcn, ExtractKey,
EqualKey, Alloc> &i)
: __hashtable_iterator<pair<const Key,Value>, Key, HashFcn,
ExtractKey, EqualKey, Alloc>(i) {}
Value &operator*(void) const { return cur->val.second; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
Value *operator->(void) const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
};
template <class Value, class Key, class HashFcn = hash<Key>,
class ExtractKey = select1st<pair<const Key, Value> >,
class EqualKey = equal_to<Key>, class Alloc = alloc>
struct CSimpleConstHashIterator
: public __hashtable_const_iterator<pair<const Key, Value>, Key,
HashFcn, ExtractKey, EqualKey,
Alloc>
{
typedef CSimpleHashIterator<Value, Key, HashFcn, ExtractKey,
EqualKey, Alloc> iterator;
typedef CSimpleConstHashIterator<Value, Key, HashFcn, ExtractKey,
EqualKey, Alloc> const_iterator;
CSimpleConstHashIterator(void)
: __hashtable_const_iterator<pair<const Key, Value>, Key, HashFcn,
ExtractKey, EqualKey, Alloc>() {}
CSimpleConstHashIterator(const iterator& i)
{
cur = i.cur;
ht = i.ht;
}
CSimpleConstHashIterator(node* n, hashtable* tab)
: __hashtable_const_iterator<pair<const Key, Value>, Key, HashFcn,
ExtractKey, EqualKey,
Alloc>(n, tab) {}
CSimpleConstHashIterator(const
__hashtable_const_iterator<pair<const Key,Value>,
Key, HashFcn, ExtractKey,
EqualKey, Alloc> &i)
: __hashtable_const_iterator<pair<const Key,Value>,
Key, HashFcn, ExtractKey,
EqualKey, Alloc>(i) {}
const Value &operator*(void) const { return cur->val.second; }
#ifndef __SGI_STL_NO_ARROW_OPERATOR
const Value *operator->(void) const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
};
Just recently I upgraded to egcs-1.1a and now the above implementation
causes link errors from collect2 when using the -frepo option of egcs.
This was not a problem with egcs-1.0.3 -frepo. The code will compile if
I do not use the -frepo option (I would rather use the -frepo, because I
am dealing with a very large code base that uses templates
extensively). Have I found a regression in egcs, or is there something
that isn't quite to the C++ Standard that is causing the newer compiler
to choke?
It seems like templates aren't getting instantiated in the right order,
which I thought was one of the things -frepo was suppose to take care
of. This would be a problem as I have read in the C++ Draft 14.6.1.3:
"The use of a _template-parameter_ as a base class implies that a class
used as a _template-argument_ must be defined and not just declared when
the class template is instantiated."
If there is something wrong with the way I am implementing this, does
anyone know how I can fix this? Is there something I have to do to
force instantiations to occur in the right order and in the right
place? I wouldn't think I would have to do explicit instantiations.
This could get very sloppy and tedious with the amount of instances I
would have to deal with. If it is a regression in egcs (God forbit),
does anyone know of a work-around for this until it is fixed?
I can email an attachment of the link errors if that would help you help
me ;)
Thanks in advance for everything.
--
Chad Gatesman
Software Engineer
More information about the Gcc
mailing list