我的问题如下。我有大量的静态const整数作为标识符。出于这个原因,我想知道是否有可能在编译时检查是否存在多个具有相同值的常量(某种静态断言...)。
我不想使用枚举,因为这些常量是在不同的模块中定义的,我不希望它们具有所有这些常量的长枚举(并且其中一些不相互关联)。 / p>
这里有一个基本的例子:
// module: foo.h
const uint32_t ELEMENT_TYPE_FOO_X = 46;
const uint32_t ELEMENT_TYPE_FOO_Y = 51;
...
// module: boo.h
const uint32_t ELEMENT_TYPE_BOO_C = 21;
const uint32_t ELEMENT_TYPE_BOO_D = 51;
错误:ELEMENT_TYPE_FOO_Y和ELEMENT_TYPE_BOO_D具有相同的值。
我根本不是专家,我想到的唯一能够检测到这个错误的是模板专业化。
template<uint32_t N>
struct element_traits {
};
template<ELEMENT_TYPE_FOO_X> {
enum { value = ELEMENT_TYPE_FOO };
};
但它似乎是一个复杂的解决方案。我不知道是否有更优雅/更好的解决方案。到目前为止我还没有找到任何东西。
提前致谢。
答案 0 :(得分:6)
你当然可以使用宏来做到这一点:
#define UNIQUE_CONSTANT(variable, value) \
const uint32_t variable = value; \
bool constant_val_##value = value;
如果两次使用相同的值,则会出现多重定义错误。
(从技术上讲,这将在链接时检测错误,而不是编译时间。)
答案 1 :(得分:0)
基于Keith的解决方案。我可以“检查”常量具有调试构建的唯一值,并跳过它以进行发布构建。
#ifdef DEBUG
#define DEFINE_UNIQUE_CONSTANT(variable, value) \
const uint32_t variable = value; \
uint32_t constant_val_##value = value;
#else
#define DEFINE_UNIQUE_CONSTANT(variable, value) \
const uint32_t variable = value;
#endif
答案 2 :(得分:0)
如果大量常量必须不同并且必须在不同的源文件中定义,那么您可以通过这种方式生成它们,例如,从包含文件名和相应常量名称的文件开始,并在每次构建时生成其余部分。
输入文件:
[foo.h]
ELEMENT_TYPE_FOO_X
ELEMENT_TYPE_FOO_Y
[boo.h]
ELEMENT_TYPE_BOO_C
ELEMENT_TYPE_BOO_D
剧本:
#!/usr/bin/env python
from ConfigParser import SafeConfigParser
from itertools import count
config = SafeConfigParser(allow_no_value=True)
config.optionxform = lambda x: x # use names as-is
config.read('input.cfg')
counter = count(1)
for filename in config.sections():
with open(filename, 'w') as f:
for (name, _), i in zip(config.items(filename), counter):
f.write("const uint32_t %s = %s;\n" % (name, i))