What's the correct way to handle not finding a key in an unordered_map? (which I am new to using)
I didn't want to use 'find' as it iterates over the full map (if I understand it), where as 'at' uses the key's hash to directly access the correct bucket so it's faster.
#include <unordered_map>
std::unordered_map<byte, byte> myMap={
{{1},{2}}
};
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(myMap.at(4));
}
void loop() {
}
This code crashes... What's the return value if the key isn't found?
Looking online it says it throws an exception. I'll be honest, I learned c++ purely on Arduino and apparently they don't use exceptions, so I don't really understand them or how to deal with them outside of 'they get thrown when an error occurs'.
Are there any clever ways to ensure that at least 'some' valid bucket is returned? Like maybe if I added a 'dummy' key:value pair last and edited the lib so that gets returned as a fail-safe instead of throwing the exception?
Basically I'm trying to make invalid keys essentially be ignored so it's at least crash-proof.
My prediction of your response on the above is... 'last isn't guarenteed, hence 'unordered' so that won't work' and 'it's up to the programmer to ensure that valid keys are being hashed when using 'at()' '
So the way my code works is that I have midi sysex messages coming in over USB, that contain an 'address' and a 'data' byte for a 'Parameter' (which both get extracted from the sysex as uint32_t and byte variables)
I have the unordered map of parameter pointers (750 of them, keyed by address) and when I do a sync to read and update the data of all parameters, my device spits out a sysex message for each one containing the data for the requested address.
So I have something along the lines of: (syntax from memory)
parameterMap.at(address)->index = data;
Most of the time my device spits out sysex messages for the specific addresses I've requested, but it also spits out (in certain cases) much longer messages with bulk data for an address block which isn't found in my map. I think that's what is causing my program to crash.
I swapped to map because iterating over potentially 750 array entries, 750 times (worst case) to find the right place to dump that data is vastly slower than the hash to bucket of the map.
I did some quick benchmarking and find() and at() seem very similar in performance and both are way faster in comparison to an array and for loop.
Why is this? I thought find simply iterated over everything in the map and returns if found or returns end() if not. How is that not the same as an array and for loop?