Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to define a map with "non-standard" key

0 views
Skip to first unread message

Toub

unread,
Jun 13, 2003, 1:52:18 PM6/13/03
to
Hi,

I'd like to create a map "like this":

struct nuclei { int Z; int A; } ;
map < nuclei, float > my_map ;

I understand I have to provide a sorting function for my key but I'm not
sure of the way to code it and pass it in the map declaration (or later?).
Would anyone help please?

Thanks!

Laurent

John Harrison

unread,
Jun 13, 2003, 2:13:14 PM6/13/03
to

"Toub" <aud...@ipno.in2p3.fr> wrote in message
news:3eea0f52$0$11650$626a...@news.free.fr...

Write this function

bool operator<(const nuclei& a, const nuclei& b)
{
// return true if a < b
...
}

There is no need to 'pass it in the map declaration', map will use operator<
automatically. Only if you didn't want map to use operator< would this be an
issue.

john


Victor Bazarov

unread,
Jun 13, 2003, 2:16:53 PM6/13/03
to
"Toub" <aud...@ipno.in2p3.fr> wrote...


There are several ways. You could define the "operator<" for
your 'nuclei' class (either a member or stand-alone function).
You could provide a class that would compare two values of
type 'nuclei' and decide which one is smaller. In the second
case you could declare your map with that comparator as the
third template argument or instantiate it and pass to the map's
constructor (in your case as the first argument).

Example of the first solution:

bool operator < (const nuclei& n1, const nuclei& n2)
{
... do what is needed to compare n1 and n2 and return
appropriate logical value...
}

Example of the second.1 solution

struct nuclei_compare
{
bool operator ()(const nuclei& n1, const nuclei& n2)
{
... do what is needed to compare n1 and n2 and return
appropriate logical value...
}
};

map < nuclei, float, nuclei_compare > my_map ;

Example of the second.2 solution

struct nuclei_compare ...

map < nuclei, float > my_map( nuclei_compare() );

HTH

Victor


Andrey Tarasevich

unread,
Jun 13, 2003, 2:53:24 PM6/13/03
to
Victor Bazarov wrote:
>> I'd like to create a map "like this":
>>
>> struct nuclei { int Z; int A; } ;
>> map < nuclei, float > my_map ;
>>
>> I understand I have to provide a sorting function for my key but I'm not
>> sure of the way to code it and pass it in the map declaration (or later?).
>> Would anyone help please?
>
> There are several ways. You could define the "operator<" for
> your 'nuclei' class (either a member or stand-alone function).
> You could provide a class that would compare two values of
> type 'nuclei' and decide which one is smaller.

Actually, in the second case there is no requirement for it to be a class. A
function pointer will do just as well:

bool nuclei_compare(const nuclei& n1, const nuclei& n2)


{
... do what is needed to compare n1 and n2 and return
appropriate logical value...
}

map < nuclei, float, bool (*)(const nuclei&, const nuclei&) >
my_map(&nuclei_compare);

> In the second
> case you could declare your map with that comparator as the
> third template argument or instantiate it and pass to the map's
> constructor (in your case as the first argument).

Or??? I don't understand how you expect this to work. Your second.2 solution
is invalid. Even if you'd implemented your comparator as polymorphic class,
it still wouldn't work. The comparator for 'std::map' cannot be implemented
as polymorphic class because the map itself always calls its methods statically.

>
> Example of the second.2 solution
>
> struct nuclei_compare ...
>
> map < nuclei, float > my_map( nuclei_compare() );

> ...

This won't even compile.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP

Andrey Tarasevich

unread,
Jun 13, 2003, 2:58:37 PM6/13/03
to
Andrey Tarasevich wrote:
>> ...

>> Example of the second.2 solution
>>
>> struct nuclei_compare ...
>>
>> map < nuclei, float > my_map( nuclei_compare() );
>> ...
>
> This won't even compile.
> ...

Hmm... The strange thing is that it does compile. What am I missing?

Andrey Tarasevich

unread,
Jun 13, 2003, 3:22:55 PM6/13/03
to
Andrey Tarasevich wrote:
>>> ...
>>> Example of the second.2 solution
>>>
>>> struct nuclei_compare ...
>>>
>>> map < nuclei, float > my_map( nuclei_compare() );
>>> ...
>>
>> This won't even compile.
>> ...
>
> Hmm... The strange thing is that it does compile. What am I missing?
> ...

I can't believe it! The moment you think you totally get this "object
definition/function declaration" issue under control it sneaks from behind and
bites you in the ass :)

Victor, the example in your second.2 solution is a declaration of a function,
not a definition of a 'std::map' object.

The question still stands: could you please elaborate on your second.2 solution.
It's not the first time I see you suggesting it. And I've never been able to
understand what exactly you are trying to achieve by it.

Victor Bazarov

unread,
Jun 13, 2003, 4:11:04 PM6/13/03
to
"Andrey Tarasevich" <andreyta...@hotmail.com> wrote...

> Andrey Tarasevich wrote:
> >>> ...
> >>> Example of the second.2 solution
> >>>
> >>> struct nuclei_compare ...
> >>>
> >>> map < nuclei, float > my_map( nuclei_compare() );
> >>> ...

Right. Bad idea.

> The question still stands: could you please elaborate on your second.2
solution.
> It's not the first time I see you suggesting it. And I've never been able
to
> understand what exactly you are trying to achieve by it.

I keep running into fact that for templates the arguments don't get
derived from expressions when object are constructed. One has to
explicitly specify the template arguments.

Thank you for reminding me.

Victor


Alexander Terekhov

unread,
Jun 13, 2003, 4:26:03 PM6/13/03
to

Andrey Tarasevich wrote:
[...]

> The question still stands: could you please elaborate on your second.2 solution.
> It's not the first time I see you suggesting it. And I've never been able to
> understand what exactly you are trying to achieve by it.

He was simply reading way too much (and "way too much" really hurts mentality)
Stroustroup, I guess. I mean TC++PL's bits like this:

<quote>

void g(priority_queue<string,String_cmp>& pq)
{
priority_queue<string> pq2(String_cmp(nocase));
pq = pq2; // ok: pq and pq2 are of the same type, pq now also uses String_cmp(nocase)
}

</quote>

Well, maybe I'm just missing and/or misunderstanding something, of course.

"~bs", y'know.

regards,
alexander.

0 new messages