Is it possible to manually define a conversion for an enum class?

前端 未结 3 2236
自闭症患者
自闭症患者 2020-12-30 18:37

Normally you can define a cast for a class by using the following syntax:

class Test {
public:
  explicit operator bool() { return false; }
};
3条回答
  •  暖寄归人
    2020-12-30 19:11

    No, but you can make a normal class type act like an enum class, using constexpr members and constructors. And then you can add all the additional member functions you want.


    Proof that it can work even with switch:

    #include 
    
    struct FakeEnum
    {
        int x;
    
        constexpr FakeEnum(int y = 0) : x(y) {}
    
        constexpr operator int() const { return x; }
    
        static const FakeEnum A, B, Z;
    };
    
    constexpr const FakeEnum FakeEnum::A{1}, FakeEnum::B{2}, FakeEnum::Z{26};
    
    std::istream& operator>>(std::istream& st, FakeEnum& fe)
    {
        int val;
        st >> val;
        fe = FakeEnum{val};
        return st;
    }
    
    int main()
    {
        std::cout << "Hello, world!\n";
        FakeEnum fe;
        std::cin >> fe;
    
        switch (fe)
        {
            case FakeEnum::A:
            std::cout << "A\n";
            break;
            case FakeEnum::B:
            std::cout << "B\n";
            break;
            case FakeEnum::Z:
            std::cout << "Z\n";
            break;
        }
    }
    

    Proof that working with switch does not require implicit interconversion with int:

    #include 
    
    /* pseudo-enum compatible with switch and not implicitly convertible to integral type */
    struct FakeEnum
    {
        enum class Values { A = 1, B = 2, Z = 26 };
        Values x;
    
        explicit constexpr FakeEnum(int y = 0) : FakeEnum{static_cast(y)} {}
        constexpr FakeEnum(Values y) : x(y) {}
    
        constexpr operator Values() const { return x; }
        explicit constexpr operator bool() const { return x == Values::Z; }
    
        static const FakeEnum A, B, Z;
    };
    
    constexpr const FakeEnum FakeEnum::A{Values::A}, FakeEnum::B{Values::B}, FakeEnum::Z{Values::Z};
    
    std::istream& operator>>(std::istream& st, FakeEnum& fe)
    {
        int val;
        st >> val;
        fe = FakeEnum(val);
        return st;
    }
    
    int main()
    {
        std::cout << "Hello, world!\n";
        FakeEnum fe;
        std::cin >> fe;
    
        switch (fe)
        {
            case FakeEnum::A:
            std::cout << "A\n";
            break;
            case FakeEnum::B:
            std::cout << "B\n";
            break;
            case FakeEnum::Z:
            std::cout << "Z\n";
            break;
        }
        // THIS ERRORS: int z = fe;
    }
    

提交回复
热议问题