Kos*_*nov 5 c++ enums refactoring protocol-buffers c++11
在我的代码库中,我有无范围枚举,没有底层类型,如下所示:
enum EFoo {
EF_AAA = 0,
EF_UNKNOWN = 1,
EF_BBB = 2,
EF_MAX
}
Run Code Online (Sandbox Code Playgroud)
我想让它成为一个 protobuf 枚举,这样它就可以在其他 protobuf 消息中直接作为枚举重用,而不是作为某种int*字段。所以我想 .proto 文件中的枚举声明将如下所示:
enum EFoo {
EF_AAA = 0;
EF_UKNOWN = 1;
EF_BBB = 2;
}
Run Code Online (Sandbox Code Playgroud)
这是一个棘手的部分。随着时间的推移,可能会添加新字段,例如EF_CCC = 3,因此我无法EF_MAX像在 C++ 代码中那样进行声明,因为它将破坏与包含类型字段的序列化消息的二进制兼容性EFoo。并且EF_MAX在整个代码库的 API 中用作类型变量的未知值,EFoo并且EF_MAX永远不会序列化。然而,有一个EFoo_ARRAYSIZEof 类型int,其语义正是EF_MAX。所以我正在考虑将所有内容替换EF_MAX为EFoo_ARRAYSIZE,但有一件事困扰着我,它将需要在某些地方执行 astatic_cast<EFoo>(EFoo_ARRAYSIZE)以避免编译器警告,并且根据标准,它将被视为未定义的行为,这可能会导致令人讨厌的行为优化和错误。
我的问题是,我该如何解决我的问题?或者也许我错了,我的解决方案将全部替换EF_MAX为static_cast<EFoo>(EFoo_ARRAYSIZE)是安全的?
如果它可能很重要,我正在谈论 C++11 标准。
来自协议缓冲区文档:
在反序列化期间,无法识别的枚举值将保留在消息中,尽管消息反序列化时如何表示它取决于语言。在支持开放枚举类型且其值超出指定符号范围的语言(例如 C++ 和 Go)中,未知枚举值只是存储为其基础整数表示形式。
在 C++ 中,如果您知道int 代表有效的枚举,则可以将 int 转换为枚举。这不是未定义的行为,而是该语言的可预测特征。
请注意,protobuf 生成的枚举(至少在今天)不是 类型enum class,而仅仅是enum。
从这里:https://developers.google.com/protocol-buffers/docs/proto3#enum
并通过研究 protoc 的输出。