I was about to use the awful enum+map trick to switch on std::strings
when I thought to see if I could let some variadic templates do the job for me and I started to play...
#include <string>
#include <iostream>
#include <functional>
#include <unordered_map>
template<typename Key = std::string, typename Fun = std::function<void(void)> >
class Switcher {
std::unordered_map<Key,Fun> map;
Fun fdefault;
public:
template<typename... O>
Switcher(const Fun& f, const Key& k, const Fun& f2, const O&... o):
Switcher(f2, o...) { map.emplace(k,f); }
template<typename... O>
Switcher(const Fun& f, const Key& k, const Key& k2, const O&... o):
Switcher(f, k2, o...) { map.emplace(k,f); }
Switcher(const Fun & f, const Key & k) { map.emplace(k,f); }
Switcher(const Fun & f) { fdefault=f; }
Switcher & operator()(const Key & k) {
if (map.count(k)) map.at(k)();
else if (fdefault) fdefault();
return *this;
}
};
int main() {
std::string s1("hi");
std::string s2("dear");
Switcher<> switcher ( //whatever std::function here , all the keys here
[](){std::cout << "Hello "; }, "hi",
[](){std::cout << "World "; }, "dear", "buddy",
[](){std::cout << "Default ";}
);
switcher(s1);
switcher(s2);
switcher("hi")("buddy")("?");
return 0;
}
Of course is not the same as a switch
statement, but it looks handy and for simple purposes it goes quite close, doesn't it?