Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > STL map compare function - can I pass a parameter?

Reply
Thread Tools

STL map compare function - can I pass a parameter?

 
 
Martoon
Guest
Posts: n/a
 
      04-19-2006
I want to instantiate an STL map with my own compare function, and I
want to pass a parameter to the compare function that will be stored
and used for all comparisons in that map instance.

As an example, let's say the map key is char* strings, and I want the
comparison based on the nth character in the string. When the map is
instantiated, I need to somehow specify n. So I might have something
like this:

class MyClass
{
public:
void MyFunction(int i);

private:
class MyCompare
{
public:
MyCompare() : m_iCharIndex(0) {}
MyCompare(int iCharIndex) : m_iCharIndex(iCharIndex) {}

bool operator()(const char* c1, const char* c2) const
{
return c1[m_iCharIndex] < c2[m_iCharIndex];
}
int m_iCharIndex;
};
};


void MyClass::MyFunction(int i)
{
// this uses default constructor for MyCompare()
std::map<const char*, float, MyCompare> myMap;

// how do I use MyCompare(i) instead?
}


I can create a map with a char* key and MyCompare as the compare
function. But what I want to do is somehow set the m_iCharIndex member
of the MyCompare class for each map that I create (so I might have one
map that keys on the 3rd character of the strings, another that keys on
the 17th character, etc.).

Is there any way that I can do something like this? I'm not actually
trying to implement an nth character compare class. That's just a
concrete example I came up with for illustration purposes. But I am
trying to find a way to pass a parameter to a compare function for each
map that I create. And that parameter will be stored and used in all
comparisons for that map instance.

Any help appreciated.

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      04-19-2006
Martoon wrote:
> I want to instantiate an STL map with my own compare function, and I
> want to pass a parameter to the compare function that will be stored
> and used for all comparisons in that map instance.
>
> As an example, let's say the map key is char* strings, and I want the
> comparison based on the nth character in the string. When the map is
> instantiated, I need to somehow specify n. So I might have something
> like this:
>
> class MyClass
> {
> public:
> void MyFunction(int i);
>
> private:
> class MyCompare
> {
> public:
> MyCompare() : m_iCharIndex(0) {}
> MyCompare(int iCharIndex) : m_iCharIndex(iCharIndex) {}


You should probalby merge the two:

MyCompare(int iCharIndex = 0) : m_iCharIndex(iCharIndex) {}

>
> bool operator()(const char* c1, const char* c2) const
> {
> return c1[m_iCharIndex] < c2[m_iCharIndex];
> }
> int m_iCharIndex;
> };
> };
>
>
> void MyClass::MyFunction(int i)
> {
> // this uses default constructor for MyCompare()
> std::map<const char*, float, MyCompare> myMap;
>
> // how do I use MyCompare(i) instead?


RTFM about 'std::map's constructors.

std::map<const char*, float, MyCompare> myMap(MyCompare(i));

> }
>
> [..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Martoon
Guest
Posts: n/a
 
      04-19-2006
Thanks! That's what I was looking for. I'm reading up on the map
constructor.

There's still one point I don't quite follow, though. I can do this:

std::map<const char*, float, MyCompare> myMap(MyCompare(i));

But if I then try to use myMap, it doesn't seem to recongize it as a
map. For example,

bool b = myMap.empty();

yeilds a compiler error "left of '.empty' must have class/struct/union
type". What am I missing here?

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      04-19-2006
Martoon wrote:
> Thanks! That's what I was looking for. I'm reading up on the map
> constructor.
>
> There's still one point I don't quite follow, though. I can do this:
>
> std::map<const char*, float, MyCompare> myMap(MyCompare(i));
>
> But if I then try to use myMap, it doesn't seem to recongize it as a
> map. For example,
>
> bool b = myMap.empty();
>
> yeilds a compiler error "left of '.empty' must have class/struct/union
> type". What am I missing here?


My fault! You need the second set of parentheses, otherwise it's
a function declaration:

std::map<const char*, float, MyCompare> myMap((MyCompare(i)));

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Martoon
Guest
Posts: n/a
 
      04-19-2006
Ahh, thanks! It's all good now.

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      04-19-2006
Martoon wrote:

> I want to instantiate an STL map with my own compare function, and I
> want to pass a parameter to the compare function that will be stored
> and used for all comparisons in that map instance.
>
> As an example, let's say the map key is char* strings, and I want the
> comparison based on the nth character in the string. When the map is
> instantiated, I need to somehow specify n. So I might have something
> like this:
>
> class MyClass
> {
> public:
> void MyFunction(int i);
>
> private:
> class MyCompare
> {
> public:
> MyCompare() : m_iCharIndex(0) {}
> MyCompare(int iCharIndex) : m_iCharIndex(iCharIndex) {}
>
> bool operator()(const char* c1, const char* c2) const
> {
> return c1[m_iCharIndex] < c2[m_iCharIndex];
> }
> int m_iCharIndex;
> };
> };

[snip]

You have received already advice on how to get this syntactically straight.
However, the code above does no look sound: I have serious doubts that
comparing strings based on their i-th character alone yields a strict weak
ordering for the data types in your application. In other words: your
comparison predicate could cause undefined behavior in std::map.


Best

Kai-Uwe Bux

 
Reply With Quote
 
Mark P
Guest
Posts: n/a
 
      04-19-2006
Kai-Uwe Bux wrote:
> Martoon wrote:
>
>> I want to instantiate an STL map with my own compare function, and I
>> want to pass a parameter to the compare function that will be stored
>> and used for all comparisons in that map instance.
>>
>> As an example, let's say the map key is char* strings, and I want the
>> comparison based on the nth character in the string. When the map is
>> instantiated, I need to somehow specify n. So I might have something
>> like this:
>>
>> class MyClass
>> {
>> public:
>> void MyFunction(int i);
>>
>> private:
>> class MyCompare
>> {
>> public:
>> MyCompare() : m_iCharIndex(0) {}
>> MyCompare(int iCharIndex) : m_iCharIndex(iCharIndex) {}
>>
>> bool operator()(const char* c1, const char* c2) const
>> {
>> return c1[m_iCharIndex] < c2[m_iCharIndex];
>> }
>> int m_iCharIndex;
>> };
>> };

> [snip]
>
> You have received already advice on how to get this syntactically straight.
> However, the code above does no look sound: I have serious doubts that
> comparing strings based on their i-th character alone yields a strict weak
> ordering for the data types in your application.


Why do you say so? Assuming that all strings do in fact have an i-th
character, this looks like a valid strict weak ordering.

On the other hand, since a map will not allow multiple keys which
compare equal, it seems that this may not be a very useful structure,
but then only the OP knows what he wants to do with this.

Mark

In other words: your
> comparison predicate could cause undefined behavior in std::map.
>
>
> Best
>
> Kai-Uwe Bux
>

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      04-20-2006
Mark P wrote:

> Kai-Uwe Bux wrote:
>> Martoon wrote:
>>
>>> I want to instantiate an STL map with my own compare function, and I
>>> want to pass a parameter to the compare function that will be stored
>>> and used for all comparisons in that map instance.
>>>
>>> As an example, let's say the map key is char* strings, and I want the
>>> comparison based on the nth character in the string. When the map is
>>> instantiated, I need to somehow specify n. So I might have something
>>> like this:
>>>
>>> class MyClass
>>> {
>>> public:
>>> void MyFunction(int i);
>>>
>>> private:
>>> class MyCompare
>>> {
>>> public:
>>> MyCompare() : m_iCharIndex(0) {}
>>> MyCompare(int iCharIndex) : m_iCharIndex(iCharIndex) {}
>>>
>>> bool operator()(const char* c1, const char* c2) const
>>> {
>>> return c1[m_iCharIndex] < c2[m_iCharIndex];
>>> }
>>> int m_iCharIndex;
>>> };
>>> };

>> [snip]
>>
>> You have received already advice on how to get this syntactically
>> straight. However, the code above does no look sound: I have serious
>> doubts that comparing strings based on their i-th character alone yields
>> a strict weak ordering for the data types in your application.

>
> Why do you say so? Assuming that all strings do in fact have an i-th
> character, this looks like a valid strict weak ordering.


That is why I said "serious doubts" instead of: it will not work.

Also, from a standards point of view, the requirement is that the predicate
defines a strict weak ordering on the *type* for the keys. No restriction
is made that only the values actually used in the map have to be ordered.


> On the other hand, since a map will not allow multiple keys which
> compare equal, it seems that this may not be a very useful structure,
> but then only the OP knows what he wants to do with this.


True, and that is why my post was carefully worded:
>> your comparison predicate could cause undefined behavior in std::map.

^^^^^

In any case, I just wanted to alert the OP of a potential pitfall in his
code. No claim on my part is made as to whether there will be trouble or
not. All I claim is that the code look somewhat dangerous.


Best

Kai-Uwe Bux
 
Reply With Quote
 
Michiel.Salters@tomtom.com
Guest
Posts: n/a
 
      04-20-2006
Kai-Uwe Bux wrote:
> I have serious doubts that comparing strings based on their i-th
> character alone yields a strict weak ordering for the data types
> in your application.


Any strict weak ordering of a domain Y is equivalent to a strict weak
ordering of domain X, if there is a deterministic mapping y = f(x).

In this case, the domain of strings Y is ordered by any strict weak
ordering
of optional<char> and the function optional<char> get_n(string s);

HTH,
Michiel Salters

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      04-20-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> Kai-Uwe Bux wrote:
>> I have serious doubts that comparing strings based on their i-th
>> character alone yields a strict weak ordering for the data types
>> in your application.

>
> Any strict weak ordering of a domain Y is equivalent to a strict weak
> ordering of domain X, if there is a deterministic mapping y = f(x).
>
> In this case, the domain of strings Y is ordered by any strict weak
> ordering
> of optional<char> and the function optional<char> get_n(string s);


Oops, my bad. I confused it for a total ordering.


Thanks

Kai-Uwe Bux
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Resorting a map (copying a map to another with different Compare) nw C++ 5 03-12-2010 01:49 PM
STL map, compare function S S C++ 5 06-24-2008 08:36 AM
key compare problem in stl map NewToCPP C++ 10 12-15-2006 12:11 PM
STL map with key as a structure compare function issue addy.varma@gmail.com C++ 2 05-04-2006 12:33 PM
stl questions: how can I compare 2 stl list? silverburgh.meryl@gmail.com C++ 5 04-16-2006 09:57 PM



Advertisments