2012-03-10 3 views
0

У меня есть структура, которая хранит информацию об ARP-пакете, и мне нужно сохранить ARP-запрос и пакет ответов вместе. Я хотел бы использовать std :: map для этого, ключевое и отображаемое значение - это ARP struct, и я бы использовал оператор find для математического ответа с запросом.C++ stl :: map find with structs

Мой вопрос: как я могу сказать map :: find, чтобы сравнивать только некоторые члены из struct.

Пример того, что я пытаюсь описать

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

    struct ipv4_address ip_sender; 
    struct ipv4_address ip_target; 
}; 

Я хотел бы сохранить весь запрос на карте, как этого

std::map<arp_packet*, arp_packet*> 

Первого соотнесенного значение является NULL, но подогреть ответный пакет приходит я буду используйте метод find, чтобы он соответствовал запросу.

Итак, как я должен выполнить то, что карта возьмет за ключ arp_packet *, и найдет ли он другой arp_packet * и сопоставит его с помощью ip_sender и ip_target?

+0

Поскольку вы храните необработанные указатели, вам просто нужно предоставить предикат, который обеспечивает соответствующее меньшее сравнение для типа 'arp_packet *' – Chad

ответ

7

A std::map принимает до 4 параметров шаблона (последние 2 имеют значения по умолчанию).

Вы использовали бы здесь третий параметр: функтор, предназначенный для сравнения двух ключей.

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; 

Будьте осторожны реализации надлежащей operator() семантики, она должна соответствовать математическими свойствами <, в частности антисимметрия и транзитивность.

+0

Я пробовал это, но он не делает то, что я хочу Возможно, карта не подходит для этой проблемы. Я хочу сначала вставить в какой-то контейнер arp_packet *, а затем, если ответ появится в этом контейнере для его запроса. – Jan

+0

@Jan: К сожалению, так как я понятия не имею, как вы на самом деле идентифицируете пакет 'request' из' 'ответа'', это довольно сложно ответить. Кажется, что вам действительно не нужно сопоставление здесь, а только контейнер с возможностью поиска, вы можете попробовать «std :: set » для хранения пакетов запросов, ожидающих ответа. –

+0

Также попробовал подход std :: set, но он также не работает так, как я хочу, но я думаю, что в конечном итоге буду использовать карту, и я буду вычислять простой хэш из пакета и использовать это как ключ. Мне нужно связать ответ на базу запросов на ipv4-адресах, и поскольку ipv4 использует 32 бит для представления адреса, я буду использовать unsigned long как hash. в запросе 0-31 бит будет ip-адресом и 32-63 ip-отправителем, в ответ порядок будет обратным. Но спасибо за информацию о карте и компараторе – Jan