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

std::map replacement

P: n/a
If you liked the functionality of std::map, but found that you
couldn't trust your implementation to handle nonstandard data
structures, how would you code a wrapper? I've produced the
following:

#include <map>

template < class keytype, class recordtype >
class pseudomap
{
private:
map< keytype, unsigned int > maptable;
CustomList<recordtype> recordlist; // custom array-like class
// with methods including
// those used below

public:
void clear() {maptable.clear();recordlist.Clear();}

recordtype& operator[] ( const keytype& key )
{
if( maptable.count(key) ) {
return( *recordlist[maptable[key]] );
}
recordlist.Add( new recordtype() );
maptable[key]=recordlist.Count-1;
return( *recordlist[maptable[key]] );
}
};

I get the feeling that there is a lot to criticize about the code
above (although it seems to work just fine) - so I'm listening :)
Needless to say not all map functionality is included - but it's good
enough for my current needs...

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #1
Share this Question
Share on Google+
25 Replies


P: n/a
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote in
news:c7**********@chessie.cirr.com:
If you liked the functionality of std::map, but found that you
couldn't trust your implementation to handle nonstandard data
structures, how would you code a wrapper? I've produced the
following:
What do you call "nonstandard data structures"?
#include <map>

template < class keytype, class recordtype >
class pseudomap
{
private:
map< keytype, unsigned int > maptable;
CustomList<recordtype> recordlist; // custom array-like class
// with methods including
// those used below

public:
void clear() {maptable.clear();recordlist.Clear();}

recordtype& operator[] ( const keytype& key )
{
if( maptable.count(key) ) {
return( *recordlist[maptable[key]] );
}
recordlist.Add( new recordtype() );
maptable[key]=recordlist.Count-1;
return( *recordlist[maptable[key]] );
}
};

I get the feeling that there is a lot to criticize about the code
above (although it seems to work just fine) - so I'm listening :)
Needless to say not all map functionality is included - but it's good
enough for my current needs...


How can we tell? You haven't stated what exactly you're trying to
accomplish!

Jul 22 '05 #2

P: n/a
Christopher Benson-Manica <at***@nospam.cyberspace.org> wrote in message news:<c7**********@chessie.cirr.com>...
If you liked the functionality of std::map, but found that you
couldn't trust your implementation to handle nonstandard data
structures, how would you code a wrapper?


By wrapping the non-standard data or implementing a proper
std::less<non_standard_data>.

Regards,
Michiel Salters
Jul 22 '05 #3

P: n/a
Michiel Salters <Mi*************@logicacmg.com> spoke thus:
By wrapping the non-standard data or implementing a proper
std::less<non_standard_data>.


Well, the key was an unsigned int (the user-defined data was the
value), so I don't think the comparison function was the problem.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #4

P: n/a
Andre Kostur <nn******@kostur.net> spoke thus:
How can we tell? You haven't stated what exactly you're trying to
accomplish!


I thought I did - to create a data structure that acts like a map but
uses a map with only simple data types as the values. As I stated,
when using a class I defined as the second map template parameter,
things broke, and as far as I can tell it isn't my fault...

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #5

P: n/a
Christopher Benson-Manica wrote:

Andre Kostur <nn******@kostur.net> spoke thus:
How can we tell? You haven't stated what exactly you're trying to
accomplish!


I thought I did - to create a data structure that acts like a map but
uses a map with only simple data types as the values. As I stated,
when using a class I defined as the second map template parameter,
things broke, and as far as I can tell it isn't my fault...


Show your class.
In almost all cases it *is* your fault.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #6

P: n/a
Karl Heinz Buchegger <kb******@gascad.at> spoke thus:
Show your class.
In almost all cases it *is* your fault.


Verbatim, with some names changed:

struct
MyClass {
private:
CustomClassA e;

public:
bool Valid;

_TDate Start;
_TDate End;
uint blockMTD;
uint blockYTD;
uint creditMTD;

bool HasNextPeriod;
_TDate nbStart;
_TDate nbEnd;
uint nbBlock;
uint nbCredit;

CustomClassB Exceptions; // list of CustomClassA's
void AddException( uint id, uint date, uint time ) {Exceptions.AddException(id,date,time);}
void AddException( const char *str ) {e.FromString(str);Exceptions.Add(e);}

EmployeeEvalInfo() {Valid=false;HasNextPeriod=false;Start=0;End=0;blo ckMTD=0;blockYTD=0;creditMTD=0;nbStart=0;nbEnd=0;n bBlock=0;nbCredit=0;}
};

Unless the implementations of CustomClassA and CustomClassB matter, I
don't see what the problem can be...

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #7

P: n/a
Christopher Benson-Manica wrote:
If you liked the functionality of std::map, but found
that you couldn't trust your implementation to handle
nonstandard data structures, how would you code a
wrapper?


I'm not clear on what you mean by "nonstandard data
structures" and why you can't just insert your objects
into a std::map directly.

Are you getting compiler errors? Are you seeing
unexpected results at runtime?
Jul 22 '05 #8

P: n/a
Derek <no**@cheese.com> spoke thus:
Are you getting compiler errors? Are you seeing
unexpected results at runtime?


Unexpected results at runtime, and the debugger points at the std::map
implementation...

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #9

P: n/a

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:c7**********@chessie.cirr.com...
Karl Heinz Buchegger <kb******@gascad.at> spoke thus:
Show your class.
In almost all cases it *is* your fault.
Verbatim, with some names changed:

struct
MyClass {
private:
CustomClassA e;

public:
bool Valid;

_TDate Start;
_TDate End;
uint blockMTD;
uint blockYTD;
uint creditMTD;

bool HasNextPeriod;
_TDate nbStart;
_TDate nbEnd;
uint nbBlock;
uint nbCredit;

CustomClassB Exceptions; // list of CustomClassA's
void AddException( uint id, uint date, uint time )

{Exceptions.AddException(id,date,time);} void AddException( const char *str ) {e.FromString(str);Exceptions.Add(e);}
EmployeeEvalInfo() {Valid=false;HasNextPeriod=false;Start=0;End=0;blo ckMTD=0;blockYTD=0;creditM
TD=0;nbStart=0;nbEnd=0;nbBlock=0;nbCredit=0;} };

Unless the implementations of CustomClassA and CustomClassB matter, I
don't see what the problem can be...


I'm sure they do matter! All of your classes used here must be default
constructible, and copyable/assignable. If that is not possible define your
map as std::map< key, boost::shard_ptr<Myclass> >

Jeff F
Jul 22 '05 #10

P: n/a
Jeff Flinn <NO****@nowhere.com> spoke thus:
I'm sure they do matter! All of your classes used here must be default
constructible, and copyable/assignable. If that is not possible define your
map as std::map< key, boost::shard_ptr<Myclass> >


Well, I can't use boost, and I can't change how these classes are
implemented, so I guess I'll stick with what I posted originally.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #11

P: n/a
Christopher Benson-Manica wrote:
Are you getting compiler errors? Are you seeing
unexpected results at runtime?


Unexpected results at runtime, and the debugger points at
the std::map implementation...


Unless you are using an ancient or highly broken standard
library, I doubt it's the std::map implementation.

More likely that your "nonstandard" value class doesn't
implement correct copy semantics or contains some other bug.
Jul 22 '05 #12

P: n/a
Christopher Benson-Manica wrote:
I'm sure they do matter! All of your classes
used here must be default constructible, and
copyable/assignable. If that is not possible define
your map as std::map< key, boost::shard_ptr<Myclass> >


Well, I can't use boost, and I can't change how these
classes are implemented, so I guess I'll stick with what
I posted originally.


Why can't you use boost? Another possibility is to
use raw pointers and manage lifetime yourself, eg,
std::map<key, MyClass*>.

If the problem is that if your classes don't use correct
copy/assignment semantics, your wrapper may be very
fragile. It may work now, but it may fail completely on
another platform or stop working when you make what seems
like an unrelated change. Best to get to the root cause
of the problem.
Jul 22 '05 #13

P: n/a
Derek <no**@cheese.com> spoke thus:
Why can't you use boost?
It isn't my decision to make.
Another possibility is to
use raw pointers and manage lifetime yourself, eg,
std::map<key, MyClass*>.
I suppose, but it'd be a hassle.
If the problem is that if your classes don't use correct
copy/assignment semantics, your wrapper may be very
fragile.


Well, if it's fragile, it's because the custom classes are fragile; I
think map< int, int > is pretty stable.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #14

P: n/a
Derek <no**@cheese.com> spoke thus:
Unless you are using an ancient or highly broken standard
library, I doubt it's the std::map implementation.
It's Borland 4, and I've found several instances where it's either
flat broken or breaks when our custom libraries are linked in.
More likely that your "nonstandard" value class doesn't
implement correct copy semantics or contains some other bug.


Possibly :)

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #15

P: n/a

"Christopher Benson-Manica" <at***@nospam.cyberspace.org> wrote in message
news:c7**********@chessie.cirr.com...
Derek <no**@cheese.com> spoke thus:
Why can't you use boost?
It isn't my decision to make.


Just curious as to the reason boost isn't allowed?
Another possibility is to
use raw pointers and manage lifetime yourself, eg,
std::map<key, MyClass*>.


I suppose, but it'd be a hassle.


You'd be better off writing a wrapper for MyClass with appropriate
default/copy constructors than re-implementing a custom map.

Your already dealing with pointers in your pseudomap class, are you not?
It's difficult to comment on your code since much of the implementation
appears to be in CustomList<recordtype> which you didn't supply. But, I
don't understand why you even have the CustomList? You could:
Untested code follows:

template < class keytype, class recordtype >
class SeverelyLimitedMap
{
private:
typedef std::map< keytype, recordtype* > tPtrs;

tPtr mPtrs;

static void DeletePtr( typename tPtrs::value_type& aPair )
{
delete aPair.second;
}

public:
void clear()
{
std::for_each( mPtrs.begin(), mPtrs.end(), DeletePtr );

mPtrs.clear();
}

recordtype& operator[] ( const keytype& key )
{
tPtrs::iterator lItr = mPtrs.find( key );

if( lItr != mPtrs.end() )
{
return *lItr;
}
else
{
return *mPtrs.insert( tPtrs::value_type( key, new
recordtype ) ).first;
}
}
};
Jeff F


Jul 22 '05 #16

P: n/a
Jeff Flinn <NO****@nowhere.com> spoke thus:
Just curious as to the reason boost isn't allowed?
I'm still trying to convince my boss that the STL is a Good Thing
(tm), with only limited success. He certainly wouldn't trust boost :)
You'd be better off writing a wrapper for MyClass with appropriate
default/copy constructors than re-implementing a custom map.
It sounds like a good exercise. I'd try that, except that I don't
know enough about MyClass' implementation to do it... (among other
things, I'm not positive that it manages its memory with malloc,
although I think it does).
Your already dealing with pointers in your pseudomap class, are you not?
It's difficult to comment on your code since much of the implementation
appears to be in CustomList<recordtype> which you didn't supply. But, I
don't understand why you even have the CustomList? You could:
Well, using the CustomList is a nod to existing code :)
Untested code follows:


I've got to do some actual work here, but I'll take a look at that
sometime - thanks.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Jul 22 '05 #17

P: n/a
Derek wrote:
Why can't you use boost? Another possibility is to
use raw pointers and manage lifetime yourself, eg,
std::map<key, MyClass*>.

I've ranted about this before. Boost is not a part of standard C++. It
is a third-party library at this time. For those of us that work in a
controlled environment (you know like that make your planes fly and
stuff?) we can't willy-nilly throw in code that's not been approved.

It's fine for writing your non-security conscious programs, but for
others you'd have to get the appropriate people to review and pass on
the Boost library.

Brian Rodenborn
Jul 22 '05 #18

P: n/a
> > Why can't you use boost?

I've ranted about this before. Boost is not a part
of standard C++. It is a third-party library at this
time. For those of us that work in a controlled
environment (you know like that make your planes fly and
stuff?) we can't willy-nilly throw in code that's not
been approved.

It's fine for writing your non-security conscious
programs, but for others you'd have to get the
appropriate people to review and pass on the Boost
library.


I share your concerns, but the only Boost component
mentioned in this thread was boost::shared_ptr. Even
though my employer does not allow Boost in general, we
do use shared_ptr because (a) it's safer than the smart
pointers we wrote in house, (b) it's very portable, and
(c) it's very likely to be in the next standard.

Of course if your application is so critical that it "makes
planes fly and stuff," then Boost may not be appropriate.
In fact, I'm not sure C++ is entirely appropriate in such
circumstances, unless used as a limited subset of the full
language. I'd rather not think what my 747 autopilot will
do when 'new' throws std::bad_alloc. ;)
Jul 22 '05 #19

P: n/a
Derek wrote:

I'd rather not think what my 747 autopilot will
do when 'new' throws std::bad_alloc. ;)


If you don't trust the author of the software to handle bad_alloc
correctly why do you trust him to handle a null pointer correctly?

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #20

P: n/a
> > I'd rather not think what my 747 autopilot will do when
'new' throws std::bad_alloc. ;)


If you don't trust the author of the software to handle
bad_alloc correctly why do you trust him to handle a null
pointer correctly?


I don't. Whether an exception goes uncaught or a null
pointer is misused, my point is that C++ might not be
the best language for some extremely mission critical
applications.
Jul 22 '05 #21

P: n/a

"Derek" <no**@cheese.com> wrote in message
news:2g************@uni-berlin.de...
I'd rather not think what my 747 autopilot will do when
> > 'new' throws std::bad_alloc. ;)

>
> If you don't trust the author of the software to handle
> bad_alloc correctly why do you trust him to handle a null
> pointer correctly?


I don't. Whether an exception goes uncaught or a null
pointer is misused, my point is that C++ might not be
the best language for some extremely mission critical
applications.


As opposed to what other language?

Jeff F
Jul 22 '05 #22

P: n/a
> > I don't. Whether an exception goes uncaught or a null
pointer is misused, my point is that C++ might not be
the best language for some extremely mission critical
applications.


As opposed to what other language?


Beats me, but I know critical software was being written
long before C++ appeared on the scene. A lot of safety
critical systems have been written in Ada over the years.
(Incidentally, Boeing uses Ada to keep 747's in the sky,
which ties in nicely with my original autopilot example.)
Jul 22 '05 #23

P: n/a
Derek wrote:
> > I'd rather not think what my 747 autopilot will do when
> > 'new' throws std::bad_alloc. ;)

>
> If you don't trust the author of the software to handle
> bad_alloc correctly why do you trust him to handle a null
> pointer correctly?


I don't. Whether an exception goes uncaught or a null
pointer is misused, my point is that C++ might not be
the best language for some extremely mission critical
applications.


So your comment about exceptions was just a cheap shot at C++. Thanks
for making your position clear.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 22 '05 #24

P: n/a
Derek wrote:
I share your concerns, but the only Boost component
mentioned in this thread was boost::shared_ptr. Even
though my employer does not allow Boost in general, we
do use shared_ptr because (a) it's safer than the smart
pointers we wrote in house, (b) it's very portable, and
(c) it's very likely to be in the next standard.
I'm sure that Boost components could be pulled out and qualified.
However, as I've said, their status is at this time that of third-party
libraries.
Of course if your application is so critical that it "makes
planes fly and stuff," then Boost may not be appropriate.
In fact, I'm not sure C++ is entirely appropriate in such
circumstances, unless used as a limited subset of the full
language. I'd rather not think what my 747 autopilot will
do when 'new' throws std::bad_alloc. ;)


Exceptions are disabled, plus we do almost all allocations during
initialization. Other than that, pretty much everything is included. We
run under a distributed real-time operating system (current VxWorks). We
use CORBA (ACE/TAO) as our middleware.


Brian Rodenborn
Jul 22 '05 #25

P: n/a
> > > > I'd rather not think what my 747 autopilot will do
> when 'new' throws std::bad_alloc. ;)

If you don't trust the author of the software to
handle bad_alloc correctly why do you trust him to
handle a null pointer correctly?


I don't. Whether an exception goes uncaught or a null
pointer is misused, my point is that C++ might not be
the best language for some extremely mission critical
applications.


So your comment about exceptions was just a cheap shot at
C++. Thanks for making your position clear.


I don't understand how an off-hand joke becomes a
"position," but call it what you wish. I meant no offense
to the C++ community. I have been a C++ developer for
years and I will continue to use C++ whenever I can.
However, I am also aware that C++ gives me a lot of rope to
hang, and writing air-tight code can sometimes be tricky.
So if you asked me to write software tomorrow that lives
will depend on, I would think long and hard before adoping
C++, despite my bias toward it.
Jul 22 '05 #26

This discussion thread is closed

Replies have been disabled for this discussion.