<map> oder doch nicht?
-
ich habe ein PacketFile (tcpdum, libpcap) und möchte feststellen, wie oft eine bestimmte IP Kombination aufgetreten ist.
Ich habe mir das folgendermaßen gedacht:
//... typedef struct flow_key_t { uint32_t src_addr; uint32_t dst_addr; }; //... map<flow_key_t, uint64_t> flow_keys; for( pkt_num_t i=0; i<total_packets; i++ ) { pReader.nextPacket(); flow_key_t flow_key = pReader.getFlowKey(); flow_keys[ pReader.getFlowKey() ] += 1; } //...
Leider geht das so nicht.
Wie mache ich das am besten und ist <map> überhaupt richtig dafür?
Viele Grüße
Bastian
-
typedef struct flow_key_t { uint32_t src_addr; uint32_t dst_addr; };
was hat das typedef da zusuchen?
ich glaube eine minimal anforderung an für ein std::map key war das der typ einen operator< überladen hatt oder man über gibt std::map ein functor der entscheidet welches ob ein flow_key_t kleiner ist als ein anders flow_key_t
kommst du damit weiter?
-
Gerard schrieb:
typedef struct flow_key_t { uint32_t src_addr; uint32_t dst_addr; };
was hat das typedef da zusuchen?
Es soll ja nur eine Deklaration und keine Definition sein.
Gerard schrieb:
ich glaube eine minimal anforderung an für ein std::map key war das der typ einen operator< überladen hatt oder man über gibt std::map ein functor der entscheidet welches ob ein flow_key_t kleiner ist als ein anders flow_key_t
kommst du damit weiter?
Sorry, nicht wirklich. Wie erzeuge ich denn so einen "functor"?
-
also in c konnte man structuren du so deklarieren
typedef struct { int a; } afoo;
in c++ ist dann
struct afoo{ int a; };
hinzugekommen
abertypedef struct afoo{ int a; };
ist sinnloss
zu nummer zwei http://www.sgi.com/tech/stl/Map.html
struct ltstr ist der functor
-
Danke für den Tip. Ich habe das jetzt so gemacht, aber leider geht das irgendwie nicht.
//... struct ltstr { bool operator()(flow_key_t& s1, flow_key_t& s2) const { return( (s1.src_addr+s1.dst_addr) < (s2.src_addr+s2.dst_addr) ); } }; map<flow_key_t, uint64_t, ltstr> flow_keys; //...
Der Compierl sagt:
trafana.cpp|78| error: template-argument ` || analyzeAllPackets(std::vector<result_t, std::allocator<result_t> >&)::ltstr' || uses local type `analyzeAllPackets(std::vector<result_t, || std::allocator<result_t> >&)::ltstr' trafana.cpp|78| error: ISO C++ forbids declaration of `flow_keys' with no type
Die frage ist natürluch, ob <map> für meinen Anwendungsfall überhaupt geeignet ist oder ob z.B. eine <hash_map> besser geeignet ist.
Ich denke ich werde so ca. 100000 - 1000000 werte vorhalten müssen.
-
Nimm die struct ltstr mal aus der Funktion raus, dann klappt das. Template-Argumente dürfen, wie die Fehlermeldung schon sagt, keine lokal definierten Typen sein.
-
Ich habe die Definition von ltstr jetzt außerhalb der Definiert. Und nun bekomme ich aber folgende Meledung:
/usr/include/g++/bits/stl_map.h: In member function `_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = flow_key_t, _Tp = uint64_t, _Compare = ltstr, _Alloc = std::allocator<std::pair<const flow_key_t, uint64_t> >]': trafana.cpp:85: instantiated from here /usr/include/g++/bits/stl_map.h:318: error: no match for call to `(ltstr) ( const flow_key_t&, const flow_key_t&)' trafana.cpp:65: error: candidates are: bool ltstr::operator()(flow_key_t&, flow_key_t&) const
-
Du nimmst zum Vergleichen Referenzen auf nicht-konstante flow_key_t, map will den Funktor aber auch für Referenzen auf konstante flow_key_ts aufrufen können:
bool operator()(const flow_key_t& s1, const flow_key_t& s2) const
Oder, wenn flow_key_t sehr klein und schnell zu kopieren ist, ganz ohne Referenz:
bool operator()(flow_key_t s1, flow_key_t s2) const