用带有 int 标识符的类替换枚举 - 不编译

Replacing enum with class with int identifiers - doesn't compile

本文关键字:枚举 替换 编译 int 标识符      更新时间:2023-10-16

我正在做一个项目,我们有一个标准枚举,如下所示:

enum Services {
      RequestShower = 611,
      RequestBath = 617,
      RequestShave = 612,
      RequestHaircut = 618
};

但我的老板说,最新的C++标准不认为enum等同于int,所以建议使用一个有点像这样的类:

class VatelPrivateService {
public:
   static const short
      RequestShower = 611,
      RequestBath = 617,
      RequestShave = 612,
      RequestHaircut = 618;
   static const char* getName(int val);
};
ostream operator<<(ostream& os, VatelPrivateService& service);

嗯,我试着这样实现:

const char* VatelPrivateService::getName(int id)
{
 #define CASE_NM(rq) case rq: return #rq
   switch(id)
   {
      CASE_NM(RequestShower);
      CASE_NM(RequestBath);
      CASE_NM(RequestShave);
      CASE_NM(RequestHaircut);
   }
#undef CASE_NM
   return "";
}
ostream& operator<<(ostream& os, const VatelPrivateService& service)
{
   os << VatelPrivateService::getName(service);
   return os;
}

并这样称呼它:

cout << "item: " << VatelPrivateService::RequestShower << endl;

但是上面的代码没有编译-get:错误C2664:"VatelPrivateService::getName":无法将参数1从"const VatelPrivteService"转换为"int">

希望你能看到我的意图。我该怎么解决这个问题?

安格斯

最新的C++标准并不认为枚举等同于int

enum的规范没有改变:枚举器仍然可以隐式转换为其底层的整型。

C++11添加了一个新概念enum class,它是一个"强类型和作用域枚举"。这种新类型的枚举不允许其枚举器隐式转换为底层的整数类型(不过,您可以使用static_cast显式强制转换(。

如果您想编写自己的作用域枚举,该枚举提供类似于enum class的语义和行为,但可用于不支持enum class的编译器,那么您应该阅读Howard Hinnant对另一个问题的回答,其中他提供了一个工作示例。

您的VatelPrivateService(实际上(是一个命名空间,而不是一个类,因为它没有数据。这意味着ostream operator<<(ostream& os, VatelPrivateService& service);不会做什么,因为传递给ostream的服务没有数据。您的值都是unsigned short类型,这意味着您应该有ostream operator<<(ostream& os, unsigned short service);。但这已经定义好了。您需要使VatelPrivateService成为一个实际的值类型类,这样它就可以保存一个值。

当然,真正的答案是,你的老板错了,枚举会一如既往地工作。不要这样做。

您的运算符重载接受VatelPrivateService的实例作为参数,或者更确切地说是对一个实例的常量引用。但是,在VatelPrivateService中定义的成员,例如传递给coutVatelPrivateService::RequestShower,属于short类型,因此即使您更改了operator<<重载的实现,使其进行编译,也不会为VatelPrivateService::RequestShower参数调用,因为这只是一个简单的short

枚举不等价于int,但通常可以隐式地转换为一和从一转换为一,如果不是,则可以使用static_cast进行转换。使用枚举实际上是我能想到的最简单的解决方案,也是我会使用的解决方案。如果需要,可以在需要的地方将其强制转换为int。

尝试

class VatelPrivateSer
{
  private:
    const int value;
    VatelPrivateSer(int value) : value(value) {};
  public:
    static const VatelPrivateSer RequestBath() { return 617; }
    static const VatelPrivateSer RequestHaircut() { return 618; }
    static const VatelPrivateSer RequestShave() { return 612; }
    static const VatelPrivateSer RequestShower() { return 611; }
    int AsInt() const { return value; }
};

你可以随时使用我的网页http://well-spun.co.uk/code_templates/enums.php:-(