Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   STL map, compare function (http://www.velocityreviews.com/forums/t621800-stl-map-compare-function.html)

S S 06-23-2008 01:27 PM

STL map, compare function
 
Hi

I have a requirement where I am declaring a map within a class.

class abc {
map <void*, void*> mMap; // I do not pass compare struct here.
....
};

Here I am not passing compare function, but I want to do it into the
constructor of class abc. Is it possible? Above void* could well be
char* and in that case user will initialize it with some char compare
function , but I don't know how to accomplish above task. Can I do
something like

abc::abc() : mMap(compare_string) {}

But above dosen't work !!

So I want to try something like function pointers, see the code below

bool comp_default(const void *a, const void *b) { return a < b; }
bool CharStringCompare(const void* a, const void* b) {return
strcmp((char*)a, (char*)b) < 0;}
struct compare_key_ {
bool operator()(const void* a, const void* b)
{
return (abc::*mComp)(a, b); // I know this is wrong as I am not
using object here
}
};

class abc {
friend struct compare_key_;
bool (abc::*mComp) (const void*, const void*) ;
map<void*, void*, compare_key_> mMap;
....
};

But above code is not the correct thing I am doing, I just wanted to
let you know the direction I am thinking? Can someone please help me
out.

Thanks
S

Kai-Uwe Bux 06-23-2008 02:19 PM

Re: STL map, compare function
 
S S wrote:

> Hi
>
> I have a requirement where I am declaring a map within a class.
>
> class abc {
> map <void*, void*> mMap; // I do not pass compare struct here.
> ...
> };
>
> Here I am not passing compare function, but I want to do it into the
> constructor of class abc. Is it possible?


No. You have to specify the type of the comparison object beforehand.

> Above void* could well be
> char* and in that case user will initialize it with some char compare
> function , but I don't know how to accomplish above task.


Sounds like a bad idea. But anyway, you can use tr1::function, somewhat
like so:

typedef tr1::function< bool(void*,void*) > void_ptr_compare;
map< void*, void*, void_ptr_compare > mMap;

Now, you can initialize mMap from anything that can be used to compare
void*.

> Can I do something like
>
> abc::abc() : mMap(compare_string) {}
>
> But above dosen't work !!


Well, that would depend on many things (including the meaning of
compare_string).

> So I want to try something like function pointers, see the code below
>
> bool comp_default(const void *a, const void *b) { return a < b; }
> bool CharStringCompare(const void* a, const void* b) {return
> strcmp((char*)a, (char*)b) < 0;}
> struct compare_key_ {
> bool operator()(const void* a, const void* b)
> {
> return (abc::*mComp)(a, b); // I know this is wrong as I am not
> using object here
> }
> };


Make the function pointer a member of compare_key_ and pass it upon
construction of compare_key_.

> class abc {
> friend struct compare_key_;
> bool (abc::*mComp) (const void*, const void*) ;
> map<void*, void*, compare_key_> mMap;
> ...
> };
>
> But above code is not the correct thing I am doing, I just wanted to
> let you know the direction I am thinking? Can someone please help me
> out.


You seem to be headed the wrong direction. What is the underlying problem
you are trying to solve. Very likely, the use of void* is already a mistake
and right now you are about to compound it.


Best

Kai-Uwe Bux

Juha Nieminen 06-23-2008 03:30 PM

Re: STL map, compare function
 
S S wrote:
> map <void*, void*> mMap; // I do not pass compare struct here.


In C++, if you feel the need to use void* (except when dealing with
some C library), that's a good sign that you are doing something wrong.

I have programmed C++ as a hobby and professionally for about 10
years, and I have never needed to use "void*". (Well, I actually have a
few times, but only when dealing with some C libraries which required
them. That's an exception.)

Anyways, std::map requires that you give the comparator type as
template parameter if the default comparator doesn't suffice. There's no
way around that.

S S 06-23-2008 05:37 PM

Re: STL map, compare function
 
On Jun 23, 7:19*pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> S S wrote:
> > Hi

>
> > I have a requirement where I am declaring a map within a class.

>
> > class abc {
> > map <void*, void*> mMap; // I do not pass compare struct here.
> > ...
> > };

>
> > Here I am not passing compare function, but I want to do it into the
> > constructor of class abc. Is it possible?

>
> No. You have to specify the type of the comparison object beforehand.


If you look for STL map's function, it says a constructor like,
map(const key_compare& k)
Not sure what it is for..

>
> > Above void* could well be
> > char* and in that case user will initialize it with some char compare
> > function , but I don't know how to accomplish above task.

>
> Sounds like a bad idea. But anyway, *you can use tr1::function, somewhat
> like so:
>
> * typedef tr1::function< bool(void*,void*) > void_ptr_compare;
> * map< void*, void*, void_ptr_compare > mMap;
>
> Now, you can initialize mMap from anything that can be used to compare
> void*.
>
> > Can I do something like

>
> > abc::abc() : mMap(compare_string) {}

>
> > But above dosen't work !!

>
> Well, that would depend on many things (including the meaning of
> compare_string).
>
> > So I want to try something like function pointers, see the code below

>
> > bool comp_default(const void *a, const void *b) { return *a < b; }
> > bool CharStringCompare(const void* a, const void* b) {return
> > strcmp((char*)a, (char*)b) < 0;}
> > struct compare_key_ {
> > * *bool operator()(const void* a, const void* b)
> > * *{
> > * * * *return (abc::*mComp)(a, b); // I know this is wrong as I am not
> > using object here
> > * *}
> > };

>
> Make the function pointer a member of compare_key_ and pass it upon
> construction of compare_key_.


This wont help probably as I need to let mComp point differently
depending on each 'abc' object.

>
> > class abc {
> > friend struct compare_key_;
> > bool (abc::*mComp) (const void*, const void*) ;
> > map<void*, void*, compare_key_> mMap;
> > ...
> > };

>
> > But above code is not the correct thing I am doing, I just wanted to
> > let you know the direction I am thinking? Can someone please help me
> > out.

>
> You seem to be headed the wrong direction. What is the underlying problem
> you are trying to solve. Very likely, the use of void* is already a mistake


I am trying to create a HashTable class (a hash implementation), here
I am using void*, it can store pointers / integers / char* /
anything....

> and right now you are about to compound it.
>
> Best
>
> Kai-Uwe Bux



Kai-Uwe Bux 06-23-2008 06:42 PM

Re: STL map, compare function
 
S S wrote:

> On Jun 23, 7:19*pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> S S wrote:
>> > Hi

>>
>> > I have a requirement where I am declaring a map within a class.

>>
>> > class abc {
>> > map <void*, void*> mMap; // I do not pass compare struct here.
>> > ...
>> > };

>>
>> > Here I am not passing compare function, but I want to do it into the
>> > constructor of class abc. Is it possible?

>>
>> No. You have to specify the type of the comparison object beforehand.

>
> If you look for STL map's function, it says a constructor like,
> map(const key_compare& k)
> Not sure what it is for..


It is for creating a map that uses k as the comparison predicate for keys.
However, that does not change the fact that the type key_compare has to be
specified beforehand. The map template takes up to four type parameters.
The third is the comparison predicate. So

map< key_type, mapped_type, key_compare >

is what you need. (The fourth argument would be the type for an allocator.)

>>
>> > Above void* could well be
>> > char* and in that case user will initialize it with some char compare
>> > function , but I don't know how to accomplish above task.

>>
>> Sounds like a bad idea. But anyway, *you can use tr1::function, somewhat
>> like so:
>>
>> typedef tr1::function< bool(void*,void*) > void_ptr_compare;
>> map< void*, void*, void_ptr_compare > mMap;
>>
>> Now, you can initialize mMap from anything that can be used to compare
>> void*.
>>
>> > Can I do something like

>>
>> > abc::abc() : mMap(compare_string) {}

>>
>> > But above dosen't work !!

>>
>> Well, that would depend on many things (including the meaning of
>> compare_string).
>>
>> > So I want to try something like function pointers, see the code below

>>
>> > bool comp_default(const void *a, const void *b) { return *a < b; }
>> > bool CharStringCompare(const void* a, const void* b) {return
>> > strcmp((char*)a, (char*)b) < 0;}
>> > struct compare_key_ {
>> > bool operator()(const void* a, const void* b)
>> > {
>> > return (abc::*mComp)(a, b); // I know this is wrong as I am not
>> > using object here
>> > }
>> > };

>>
>> Make the function pointer a member of compare_key_ and pass it upon
>> construction of compare_key_.

>
> This wont help probably as I need to let mComp point differently
> depending on each 'abc' object.


And your point is? So, abc looks like so:

class abc {

map< void*, void*, compare_key_ > mMap;

public:

abc ( ..., bool(*comparison_ptr)(void*,void*) )
: mMap( compare_key_( comparison_ptr ) )
{}

...

};

However, tr1::function is more flexible than compare_key_ anyway.


>> > class abc {
>> > friend struct compare_key_;
>> > bool (abc::*mComp) (const void*, const void*) ;
>> > map<void*, void*, compare_key_> mMap;
>> > ...
>> > };

>>
>> > But above code is not the correct thing I am doing, I just wanted to
>> > let you know the direction I am thinking? Can someone please help me
>> > out.

>>
>> You seem to be headed the wrong direction. What is the underlying problem
>> you are trying to solve. Very likely, the use of void* is already a
>> mistake

>
> I am trying to create a HashTable class (a hash implementation), here
> I am using void*, it can store pointers / integers / char* /
> anything....


No need for void*. Make your hash table a template.

template < typename KeyType, typename MappedType, typename HashFct >
class hash_table {
public:

hash_table( HashFct const & f = HashFct() );

void insert( KeyType const & key, MappedType const & value );#

...

};

It is to be used as follows:

hash_table< int, int, IntHash >


One could even go on and provide a default for HastFct that has
specializations for built-in types and other bells and whistles.



BTW: you could just use the hash table from the upcoming standard.
tr1::unordered_map might be more or less what you are looking for.




Best

Kai-Uwe Bux

James Kanze 06-24-2008 08:36 AM

Re: STL map, compare function
 
On Jun 23, 3:27 pm, S S <sarvesh.si...@gmail.com> wrote:

> I have a requirement where I am declaring a map within a class.


> class abc {
> map <void*, void*> mMap; // I do not pass compare struct here.
> ...
> };


> Here I am not passing compare function, but I want to do it
> into the constructor of class abc.


There are two issues: the type of the comparator, and its
"value". The type becomes part of the type of the map, and must
be specified when you declare the map. (The map itself holds an
instance of this type, so the compiler must know its size.) The
value can be specified when you initialize the object, in this
case, in the initializer list of abc::abc. (It cannot be
changed later, except with swap, for obvious reasons.)

By default, the *type* of the comparator is std::less<Key>.
Since all instances of this class have the same behavior,
there's never any point of setting it to a particular value in
the constructor, but this is not necessarily true for other
comparators. If you declare:

map< void*, void*, bool (*)( void*, void* ) > mMap ;

for example, you almost certainly want to pass an actual
instance of the comparator to the constructor. (The default
value here is a null pointer, which isn't going to work too
well.)

> Is it possible? Above void* could well be char* and in that
> case user will initialize it with some char compare function ,
> but I don't know how to accomplish above task. Can I do
> something like


> abc::abc() : mMap(compare_string) {}


> But above dosen't work !!


It does if you declare mMap so that it takes a comparator of
type compare_string. (Or if compare_string has the type
std::less< key_type >, but of course, there's no point in it in
that case.)

> So I want to try something like function pointers, see the
> code below


> bool comp_default(const void *a, const void *b) { return a < b; }
> bool CharStringCompare(const void* a, const void* b) {return
> strcmp((char*)a, (char*)b) < 0;}
> struct compare_key_ {
> bool operator()(const void* a, const void* b)
> {
> return (abc::*mComp)(a, b); // I know this is wrong as I am not
> using object here
> }
> };


You don't need the structure.

> class abc {
> friend struct compare_key_;
> bool (abc::*mComp) (const void*, const void*) ;
> map<void*, void*, compare_key_> mMap;


Why not
std::map< void*, void*, bool (*)( void const*, void const* ) >
mMap ;
initialized with:

abc::abc()
: mMap( &CharStringCompare )
...

> ...


> };


> But above code is not the correct thing I am doing, I just
> wanted to let you know the direction I am thinking? Can
> someone please help me out.


Well, I'm very suspicious of your use of void* to begin with,
and I think you probably have to think about const correctness a
bit more as well. But there's no problem of having a comparator
which does something different depending on its state; a pointer
to function, for example (which will do something different
depending on which function it points to).

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


All times are GMT. The time now is 01:10 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57