なんか…ライフワークのようになっている賢い列挙型の追求。
operator <=
を∈
と見立てて。
とりあえず9個まで対応。
#include <iostream> template<typename T, int N> class Set { public: Set(T a1, T a2) : value_(a1), set_(a2) {} Set(T a1, T a2, T a3) : value_(a1), set_(a2, a3) {} Set(T a1, T a2, T a3, T a4) : value_(a1), set_(a2, a3, a4) {} Set(T a1, T a2, T a3, T a4, T a5) : value_(a1), set_(a2, a3, a4, a5) {} Set(T a1, T a2, T a3, T a4, T a5, T a6) : value_(a1), set_(a2, a3, a4, a5, a6) {} Set(T a1, T a2, T a3, T a4, T a5, T a6, T a7) : value_(a1), set_(a2, a3, a4, a5, a6, a7) {} Set(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8) : value_(a1), set_(a2, a3, a4, a5, a6, a7, a8) {} Set(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9) : value_(a1), set_(a2, a3, a4, a5, a6, a7, a8, a9) {} bool includes(T value) const { return (value == value_) || set_.includes(value); } private: const T value_; const Set<T, N-1> set_; }; template<typename T> class Set<T, 1> { public: Set(T a1) : value_(a1) {} bool includes(T value) const { return (value == value_); } private: T value_; }; template<typename T, int N> bool operator <= (T value, const Set<T, N>& set) { return set.includes(value); } template<typename T> Set<T, 1> setOf(T a1) { return Set<T, 1>(a1); } template<typename T> Set<T, 2> setOf(T a1, T a2) { return Set<T, 2>(a1, a2); } template<typename T> Set<T, 3> setOf(T a1, T a2, T a3) { return Set<T, 3>(a1, a2, a3); } template<typename T> Set<T, 4> setOf(T a1, T a2, T a3, T a4) { return Set<T, 4>(a1, a2, a3, a4); } template<typename T> Set<T, 5> setOf(T a1, T a2, T a3, T a4, T a5) { return Set<T, 5>(a1, a2, a3, a4, a5); } template<typename T> Set<T, 6> setOf(T a1, T a2, T a3, T a4, T a5, T a6) { return Set<T, 6>(a1, a2, a3, a4, a5, a6); } template<typename T> Set<T, 7> setOf(T a1, T a2, T a3, T a4, T a5, T a6, T a7) { return Set<T, 7>(a1, a2, a3, a4, a5, a6, a7); } template<typename T> Set<T, 8> setOf(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8) { return Set<T, 8>(a1, a2, a3, a4, a5, a6, a7, a8); } template<typename T> Set<T, 9> setOf(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9) { return Set<T, 9>(a1, a2, a3, a4, a5, a6, a7, a8, a9); } enum Kanto { Chiba, Gunma, Ibaraki, Kanagawa, Saitama, Tochigi, Tokyo }; void hantei(Kanto k) { if(k <= setOf(Gunma, Ibaraki, Tochigi)) { std::cout << "北関東" << std::endl; } else if(k <= setOf(Chiba, Kanagawa, Saitama, Tokyo)) { std::cout << "南関東" << std::endl; } else { std::cout << "どこだ?" << std::endl; } }
こういう場合、多態をつかって解決するのが正当なのだろうということに、書き上げてから気がついた。