![]() |
1
14
有几种方法可以检查这个编译时,但它们可能并不总是对您有效。首先在msgfoo2a之前插入一个“marker”枚举值。
现在我们需要一种方法来确保
负数数组声明大小为负的数组是错误的。这看起来有点难看,但很管用。
如果marker_1_dont_use大于base_2_val,几乎所有编写过的编译器都会生成错误。gcc指出:
静态断言
如果编译器支持c11,则可以使用
gcc发出以下消息:
|
![]() |
2
7
我在您的需求中没有看到“漂亮的”,所以我提交了这个使用boost预处理器库实现的解决方案。 作为一个预先声明,我没有使用boost.preprocessor很多次,我只在这里提供的测试用例中测试过它,所以可能会有bug,而且可能有一种更简单、更干净的方法来完成这项工作。我当然欢迎评论、更正、建议、侮辱等。 我们走到这里:
我们可以这样使用它:
枚举器值是可选的;此代码生成的枚举等效于:
它还生成一个健全性检查函数,该函数包含一个switch语句,如中所述 Ben Voigt's answer . 如果我们更改枚举声明使其具有非唯一的枚举器值,例如,
它不会编译(VisualC++)报告预期 错误C2196:已使用大小写值“1” ) 也要感谢马蒂厄M., whose answer to another question 让我对boost预处理器库感兴趣。 |
![]() |
3
3
我不相信有一种方法可以用语言本身检测到这一点,考虑到有些情况下,您可能希望两个枚举值相同。但是,您可以始终确保所有显式设置的项都位于列表的顶部:
只要赋值在顶部,就不可能发生冲突,除非由于某种原因宏扩展为相同的值。 通常,通过为每个msgfoox组指定固定的位数,并确保每个组不会溢出分配的位数,可以解决此问题。“位数”解决方案很好,因为它允许按位测试确定某个消息属于哪个消息组。但是没有内置的语言功能来执行此操作,因为对于具有相同值的两个枚举,存在合法的情况:
|
![]() |
4
3
我不知道有什么可以自动检查所有枚举成员,但如果您想检查初始化器(或它们所依赖的宏)的未来更改是否不会导致冲突:
如果任何一个整型值被重用,都会导致编译器错误,大多数编译器甚至会告诉您哪个值(数值)是个问题。 |
![]() |
5
1
您可以使用 Boost.Preprocessor -时间是否值得是另一回事。 如果你正在移动到C++,也许(提议的)Boo.EnUM适合你(可以通过 Boost Vault ) |
![]() |
6
1
虽然我们没有完整的反射,但如果您可以重新列出枚举值,则可以解决此问题。 在某个地方这是宣布的:
在其他地方,我们制造这种机器:
一旦你有了这台机器(它需要C++ 11),我们可以做如下操作:
在编译时,我们将确保没有两个元素是相等的。 这需要o(n)递归深度和o(n^2)编译器在编译时工作,因此对于非常大的枚举,这可能会导致问题。o(lg(n))深度和o(n lg(n))常数因子大得多的功可以通过首先对元素列表进行排序来完成,但这是非常多的工作。 对于C++ 17提出的枚举反射代码,在不影响元素的情况下,这是可行的。 |
![]() |
7
0
我不完全喜欢这里已经发布的任何答案,但他们给了我一些想法。关键技术是依赖ben voight使用switch语句的答案。如果一个交换机中有多个实例共享同一个数字,则会出现编译错误。 最有用的是我自己和可能的原始海报,这不需要任何C++特性。 为了把事情弄清楚,我用了Aaronps的答案 How can I avoid repeating myself when creating a C++ enum and a dependent data structure? 首先,在某个地方定义这个标题:
现在,每当需要枚举时:
最后,需要这些行才能实际进行枚举:
|
![]() |
rookie · 检查函数模板的所有参数包参数是否属于int 1 年前 |
![]() |
ivaigult · -W转换和隐式字符串到布尔类型转换 1 年前 |
![]() |
rainer · 后台插入程序的初始化 1 年前 |
![]() |
Community wiki · 以理智、安全和高效的方式复制文件 1 年前 |
|
Shefali Kanaujia · 对C中向量的向量进行排序++ 1 年前 |
|
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |