【问题标题】:Is there a way to have an operator= for an enum?有没有办法让 operator= 用于枚举?
【发布时间】:2016-07-24 13:28:33
【问题描述】:

我有一个枚举,但我想要一个赋值运算符,以便它能够分配一个不是原始枚举的类型。例如

enum class X : int
{
  A, B, C, D
}

enum class Y : char
{
  A, B, C, D
}

Y& operator=(Y& lhs, X rhs)
{
  return Y = static_cast<Y>(X);
}

但我收到了'operator =' must be a non-static member。有没有办法做到这一点?

【问题讨论】:

  • 我无法想象一个好的用例。你能帮帮我吗?
  • @BarryTheHatchet,我正在尝试更新一些过时的代码。他们在两个不同的地方使用相同的常量,但在一个地方,它的大小为 1 字节,另一个大小为 2。我宁愿不改变结构的二进制兼容性,以防破坏某些东西。跨度>
  • 如果您将原始代码称为过时的,我猜它没有使用enum class,我猜这是您所做的修改。那是对的吗?如果是这样,是否也可以接受不使用enum class 的替代方案?
  • @hvd,它使用intchar,甚至不是枚举。
  • 那么布赖恩的回答正是我会发布的。如果我是你,我会放弃enum class,没有它你可以实现你想要的。

标签: c++ c++11 enums operator-overloading assignment-operator


【解决方案1】:

您不能,因为正如错误消息告诉您的那样,operator= 只能是非静态成员函数,而枚举不能有成员。如果您真的希望能够从不同的枚举进行分配,也许您应该将 Y 设为一个类。另一种可能性是编写一个辅助函数来执行分配。

【讨论】:

  • 嗯,这很不幸。 :( 将Y 设为一个类可能会在打字方面造成更多麻烦...
  • @Adrian 打字不麻烦。隐藏的逻辑错误是麻烦。隐式转换隐藏了细微的逻辑错误。
  • 通过输入麻烦,我的意思是每个枚举(类和枚举)将有 2 种类型,枚举位于第二级。我猜这并不可怕,但很烦人。 class ByteX { enum X { A, ... }; }; class WordX { enum X { A, ... }; }; class DWordX { enum X { A, ... }; }; void fn() { DWordX x = WordX::X::A; }。或者我猜他们都可以引用字节一,或者在外部定义字节枚举......
【解决方案2】:

枚举类是一种您可以避免的繁琐结构。只需将旧枚举包装在结构中即可:

#include <iostream>

struct X
{
  enum enum_type { A, B, C, D };
  typedef int value_type;
  value_type value;

  X(enum_type value) : value(value) {}
  operator enum_type () const { return static_cast<enum_type>(value); }
};

struct Y
{
  enum enum_type { A, B, C, D };
  typedef char value_type;
  value_type value;

  Y(enum_type value) : value(value) {}
  operator enum_type () const { return static_cast<enum_type>(value); }

  Y& operator = (X rhs) {
    value = rhs;
    return *this;
  }
};

int main()
{
    X x = X::A;
    Y y = Y::B;
    std::cout << y << '\n';
    y = x;
    std::cout << y << '\n';
}

【讨论】:

  • 不要鼓励黑客而不是干净的解决方案。如果您想要范围枚举,那么枚举类正是您所需要的。编写一个辅助函数,这是一个小技巧。
【解决方案3】:

您可以编写转换函数而不是转换运算符。无论如何,这是更好的形式,因为它在呼叫现场清楚地表达了意图。

enum class X : int
{
    A, B, C, D
};

enum class Y : char
{
    A, B, C, D
};

Y to_y(X rhs)
{
    auto as_int = static_cast<int>(rhs);  // allowed
    auto as_char = static_cast<char>(as_int); // allowed if the int is known to fit
    return static_cast<Y>(as_char); // allowed if the char is known to be the right value
}

int main()
{
    auto x = X::C;

    auto y = to_y(x);

    return 0;
}

【讨论】:

  • 谢谢,但我希望它是隐含的,因为它无处不在。
  • 如果它无处不在,你绝对不希望它是隐含的。
  • 是的,我愿意。转换只是从类型X 到类型Y 并返回。它们代表相同的信息,但大小不同。他们永远不会互相溢出。绝对没有理由不应该是隐含的。
  • 所以使用老式的enum 而不是enum class
  • 不,我不想隐式转换为数字。仅限于我的规范类型。
猜你喜欢
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
相关资源
最近更新 更多