C ++ stl :: búsqueda de mapas con estructuras

I have struct that store info about ARP packet and I need to save the ARP request and reply packet together. I would like to use std::map for this, the key and mapped value is that ARP struct, and I would be using the find operator to math the reply with request.

My question is how can I say map::find to compare only some members from struct.

Example of what I'm trying to describe

struct arp_packet : public packet_info
{
    u_short type;   // 0x0001 request
                    // 0x0002 reply

    struct ipv4_address ip_sender;
    struct ipv4_address ip_target;
};

I would save all request in map like this

std::map<arp_packet*, arp_packet*>

First the mapped value is NULL but whet the reply packet comes I will use the find method to match it to request.

So how should I accomplist that the map would take as key the arp_packet *, and in find it would take the another arp_packet * and match it using ip_sender and ip_target?

preguntado el 10 de marzo de 12 a las 15:03

Since you're storing raw pointers, you simply need to provide a predicate that provides an appropriate less-than comparison for type arp_packet* -

1 Respuestas

A std::map accepts up to 4 template parameters (the last 2 have default values).

You would be using the 3rd parameter here: a functor meant to compare two keys.

struct ArpComparator {
  bool operator()(arp_packet* const left, arp_packet* const right) {
    // compare the fields you need here
  }
};

typedef std::map<arp_packet*, arp_packet*, ArpComparator> ArpMap;

Be careful about implementing a proper operator() semantics, it should match the mathematical properties of <notablemente antisymmetry y transitividad.

respondido 10 mar '12, 15:03

I tried this but it isn't doing what i want Maybe the map is not suited for this problem. What I want is to first insert into some container an arp_packet* and then if the reply comes looks in this container for its request counterpart. - Ene

@Jan: unfortunately, since I have no idea how you actually identify the request packet from the reply one, it's kinda hard to answer. It seems though that you do not really need a mapping here, merely a searchable container, you could try std::set<arp_packet*, ArpComparator> to hold onto the request packets waiting for a reply. - Matthieu M.

Also tried the std::set approach however it also don't work as I want, but I think that I will use eventually use map and I will calculate simple hash from the packet and use that as a key. I need to bound reply to request base on ipv4 addresses and since ipv4 use 32 bit to represent the address I will use unsigned long as hash. in request the 0-31 bit will be ip target and 32-63 ip sender, in reply the order will be reverse. But thanks for informations about map and the comparator - Ene

@Jan: the number of bits in unsigned long is implementation defined and depends on the platform, better use uint32_t from the C header <stdint.h>. You could use that as the map key, by the way: std::map<uint32_t, arp_packet*>. - Matthieu M.

That's a good point, however uint32_t is not enough, uint64_t on the other hand is what it needs. Thanks. - Ene

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.