std::map
+ C ++ 11 modello lambdas senza enumerazioni
unordered_map
per il potenziale ammortizzato O(1)
: qual è il modo migliore per utilizzare una HashMap in C ++?
#include <functional>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
int main() {
int result;
const std::unordered_map<std::string,std::function<void()>> m{
{"one", [&](){ result = 1; }},
{"two", [&](){ result = 2; }},
{"three", [&](){ result = 3; }},
};
const auto end = m.end();
std::vector<std::string> strings{"one", "two", "three", "foobar"};
for (const auto& s : strings) {
auto it = m.find(s);
if (it != end) {
it->second();
} else {
result = -1;
}
std::cout << s << " " << result << std::endl;
}
}
Produzione:
one 1
two 2
three 3
foobar -1
Utilizzo dei metodi interni con static
Per utilizzare questo modello in modo efficiente all'interno delle classi, inizializzare staticamente la mappa lambda, oppure si paga O(n)
ogni volta per crearla da zero.
Qui possiamo {}
evitare l' inizializzazione di una static
variabile di metodo: variabili statiche nei metodi di classe , ma potremmo anche usare i metodi descritti in: costruttori statici in C ++? Devo inizializzare oggetti statici privati
Era necessario trasformare la cattura del contesto lambda [&]
in un argomento, o che sarebbe stato indefinito: const static auto lambda utilizzato con la cattura per riferimento
Esempio che produce lo stesso output di cui sopra:
#include <functional>
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
class RangeSwitch {
public:
void method(std::string key, int &result) {
static const std::unordered_map<std::string,std::function<void(int&)>> m{
{"one", [](int& result){ result = 1; }},
{"two", [](int& result){ result = 2; }},
{"three", [](int& result){ result = 3; }},
};
static const auto end = m.end();
auto it = m.find(key);
if (it != end) {
it->second(result);
} else {
result = -1;
}
}
};
int main() {
RangeSwitch rangeSwitch;
int result;
std::vector<std::string> strings{"one", "two", "three", "foobar"};
for (const auto& s : strings) {
rangeSwitch.method(s, result);
std::cout << s << " " << result << std::endl;
}
}