constexpr auto execute(const int& i) { (execute_if<Is>(i), ...); }
#include <map> #include <iostream> std::map <int, void (*) ()> map; template <int i> void f (); template <> void f <1> () { std::cout << "f1\n"; } template <> void f <2> () { std::cout << "f2\n"; } template <> void f <3> () { std::cout << "f3\n"; } template <> void f <4> () { std::cout << "f4\n"; } template <> void f <5> () { std::cout << "f5\n"; } template <int ... Is> struct Dispatcher { template <int first> void execute_if (int i) { if (first == i) { std::cout << "Execute f" << i << " via template\n"; f <first> (); } } template <int first, int second, int... rest> void execute_if (int i) { if (first == i) { std::cout << "Execute f" << i << " via template\n"; f <first> (); } else execute_if <second, rest...> (i); } void execute (const int& i) { execute_if <Is...> (i); } void execute (int& i) { std::cout << "Execute f" << i << " via map\n"; map.at (i) (); } }; int main() { map [1] = f <1>; map [2] = f <2>; map [3] = f <3>; map [4] = f <4>; map [5] = f <5>; Dispatcher <1, 2, 4> dispatcher; dispatcher.execute (2); int i = 4; dispatcher.execute (i); }
Live Demo
#include <vector> #include <iostream> template <int i> void f (); template <> void f <1> () { std::cout << "f1\n"; } template <> void f <2> () { std::cout << "f2\n"; } template <> void f <3> () { std::cout << "f3\n"; } template <> void f <4> () { std::cout << "f4\n"; } template <> void f <5> () { std::cout << "f5\n"; } using ve = std::pair <int, void (*) ()>; template <int ... Is> struct Dispatcher { template <int first> void execute_if (int i) { if (first == i) { std::cout << "Execute f" << i << " via template\n"; f <first> (); } } template <int first, int second, int... rest> void execute_if (int i) { if (first == i) { std::cout << "Execute f" << i << " via template\n"; f <first> (); } else execute_if <second, rest...> (i); } void execute (const int& i) { execute_if <Is...> (i); } void execute (int& i) { std::cout << "Execute f" << i << " via binary search\n"; auto lb = lower_bound (indexes.begin (), indexes.end (), ve (i, nullptr), [] (ve p1, ve p2) { return p1.first < p2.first; }); if (lb != indexes.end () && lb->first == i) lb->second (); } template <int first> void append_index () { indexes.emplace_back (ve (first, f <first>)); } template <int first, int second, int... rest> void append_index () { append_index <first> (); append_index <second, rest...> (); } Dispatcher () { append_index <Is...> (); } private: std::vector <ve> indexes; }; int main() { Dispatcher <1, 2, 4> dispatcher; dispatcher.execute (2); int i = 4; dispatcher.execute (i); }
Live Demo