51

通常,您可以使用以下语法为类定义强制转换:

class Test {
public:
  explicit operator bool() { return false; }
};

有没有办法做到这一点或类似的事情enum class

4

3 回答 3

26

不,这不对。

实际上, anenum class根本就不是类。class仅使用该关键字是因为突然将 unscoped 更改enum为 scopedenum将意味着重新处理所有枚举代码。所以委员会决定为了区分新式和旧式枚举,新的枚举将被标记为class,因为它已经是一个关键字,所以 no不能在 C++ 中enum命名。class他们本可以选择另一个,无论如何这不会更有意义。

然而,尽管有class关键字,它们仍然是常规枚举,因为括号内只允许使用枚举数(以及可能分配给它们的值)。

于 2012-10-05T20:37:29.483 回答
18

constexpr不,但是您可以使用成员和构造函数使普通类类型像枚举类一样工作。然后你可以添加所有你想要的附加成员函数。


证明它甚至可以使用switch

#include <iostream>

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;
    }
}

证明使用switch不需要与 的隐式相互转换int

#include <iostream>

/* 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<Values>(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;
}
于 2012-10-05T22:03:40.050 回答
4

您不能在 C++ 中定义非成员强制转换运算符。而且您当然不能为枚举定义成员函数。所以我建议你做自由函数来将你的枚举转换为其他类型,就像你实现强制转换运算符一样。

例如

bool TestToBool(enum_e val)
{
    return false;
}

const char *TestToString(enum_e val)
{
    return "false";
}

有一种将这些枚举关联到布尔值的好方法,您必须将其拆分为两个文件 .h 和 .cpp。如果它有帮助,那就是:

枚举.h

///////////////////////////////
// enum.h
#ifdef CPP_FILE
#define ENUMBOOL_ENTRY(A, B)            { (enum_e) A, (bool) B },
struct EnumBool
{
    enum_e  enumVal;
    bool    boolVal;
};
#else
#define ENUMBOOL_ENTRY(A, B)            A,
#endif


#ifdef CPP_FILE
static EnumBool enumBoolTable[] = {
#else
enum enum_e
{
#endif
ENUMBOOL_ENTRY(ItemA, true),
ENUMBOOL_ENTRY(ItemB, false),
...
};

bool EnumToBool(enum_e val);

枚举.cpp

///////////////////////////////
// enum.cpp
#define CPP_FILE
#include "enum.h"

bool EnumToBool(enum_e val)
    //implement

我没有编译它,所以如果它有任何错误,请放轻松:)。

于 2012-10-05T20:36:25.677 回答