エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

二面性列挙型

#include <cassert>

enum Youbi { Getsu, Ka, Sui, Moku, Kin, Do, Nichi };

enum DayOfWeek { Sun, Mon, Tue, Wed, Thu, Fri, Sat };

class Dual
{
public:
    Dual() : value_(Getsu) {}
    explicit Dual(Youbi value) : value_(value) {}
    explicit Dual(DayOfWeek value) : value_(dayOfWeekToYoubi(value)) {}

    Dual& operator = (Youbi value)
    {
        assert((Getsu <= value) && (value <= Nichi));
        value_ = value;
    }

    Dual& operator = (DayOfWeek value)
    {
        value_ = dayOfWeekToYoubi(value);
    }

    operator Youbi () const
    {
        return value_;
    }

    operator DayOfWeek() const
    {
        switch(value_)
        {
        case Getsu: return Mon;
        case Ka:    return Tue;
        case Sui:   return Wed;
        case Moku:  return Thu;
        case Kin:   return Fri;
        case Do:    return Sat;
        case Nichi: return Sun;
        }
    }

private:
    Youbi dayOfWeekToYoubi(DayOfWeek value)
    {
        switch(value)
        {
        case Sun: return Nichi;
        case Mon: return Getsu;
        case Tue: return Ka;
        case Wed: return Sui;
        case Thu: return Moku;
        case Fri: return Kin;
        case Sat: return Do;
        default: assert(false);
        }
    }

    Youbi value_;
};

#include <iostream>

int main(int, char* [])
{
    Dual dual;

    // どちらからも代入できる
    dual = Getsu;
    dual = Mon;

    // どちらにも代入できる
    Youbi     youbi     = dual;
    DayOfWeek dayOfWeek = dual;

    std::cout << youbi << std::endl;
    std::cout << dayOfWeek << std::endl;

    // 双方向の変換関数のように
    youbi     = Dual(Sun);
    dayOfWeek = Dual(Nichi);

    std::cout << youbi << std::endl;
    std::cout << dayOfWeek << std::endl;

    return 0;
}

ダークサイドを覗き込んでます。