用带有 int 标识符的类替换枚举 - 不编译
Replacing enum with class with int identifiers - doesn't compile
我正在做一个项目,我们有一个标准枚举,如下所示:
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
中定义的成员,例如传递给cout
的VatelPrivateService::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:-(
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 打印没有铸件的枚举可以在C++中吗?
- 枚举成员与静态 int 成员?
- 替换枚举以最大化编译时间检查的最佳方法
- C++ 中的枚举类 - 替换- 在 C# 中
- 枚举类的c++typedef/类型替换
- 将枚举替换为模板 c++ 中的类
- 用带有 int 标识符的类替换枚举 - 不编译