用带有int标识符的类替换enum - 不能编译

时间:2011-10-21 17:47:04

标签: c++

我正在开发一个项目,我们有一个像这样的标准枚举:

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;

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

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

安格斯

4 个答案:

答案 0 :(得分:6)

  

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

enum的规范没有改变:枚举器仍可隐式转换为其基础整数类型。

C ++ 11增加了一个新概念enum class,它是一个“强类型和范围的枚举”。这种新类型的枚举不允许将其枚举器隐式转换为基础整数类型(但是,您可以使用static_cast明确强制转换。)

如果要编写自己的作用域枚举,提供与enum class类似的语义和行为,但可以在不支持enum class的编译器上使用,则应阅读Howard Hinnant's answer to this other question,其中提供了一个工作实例。

答案 1 :(得分:3)

您的VatelPrivateService(实际上)是名称空间,而不是类,因为它没有数据。这意味着ostream operator<<(ostream& os, VatelPrivateService& service);不会做太多,因为传递给ostream的服务没有数据。您的值均为unsigned short类型,这意味着您应该拥有ostream operator<<(ostream& os, unsigned short service);。除了已经定义的。您需要将VatelPrivateService设为实际的值类型类,因此它包含一个值以使其成为可能。

当然,真正的答案是,你的老板是错的,enums会像往常一样工作。不要这样做。

答案 2 :(得分:1)

您的运算符重载接受VatelPrivateService的实例作为参数,或者更确切地说是对一个的const引用。但是VatelPrivateService中定义的成员,例如VatelPrivateService::RequestShower,您传递给cout的成员属于short,所以即使您更改了operator<<的实现重载,以便它编译它仍然不会被调用VatelPrivateService::RequestShower参数,因为这只是一个简单的short

枚举不等同于int,但通常可以隐式转换为一个,如果不是,则可以使用static_cast进行转换。使用枚举实际上是我能想到的最简单的解决方案,而我将使用的解决方案可以根据需要将其转换为需要的int。

答案 3 :(得分:0)

尝试

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: - )