【发布时间】:2012-11-09 18:38:40
【问题描述】:
我想使用 constexpr 填充一个枚举数组。 数组的内容遵循一定的规律。
我有一个枚举,将 ASCII 字符集分为四类。
enum Type {
Alphabet,
Number,
Symbol,
Other,
};
constexpr Type table[128] = /* blah blah */;
我想要一个包含 128 个 Type 的数组。它们可以在一个结构中。
数组的索引将对应ASCII字符,值为每个字符的Type。
所以我可以查询这个数组来找出一个 ASCII 字符属于哪个类别。类似的东西
char c = RandomFunction();
if (table[c] == Alphabet)
DoSomething();
我想知道如果没有一些冗长的宏 hack,这是否可行。
目前,我通过执行以下操作来初始化表。
constexpr bool IsAlphabet (char c) {
return ((c >= 0x41 && c <= 0x5A) ||
(c >= 0x61 && c <= 0x7A));
}
constexpr bool IsNumber (char c) { /* blah blah */ }
constexpr bool IsSymbol (char c) { /* blah blah */ }
constexpr Type whichCategory (char c) { /* blah blah */ }
constexpr Type table[128] = { INITIALIZE };
INITIALIZE 是一些非常冗长的宏 hack 的入口点。
类似的东西
#define INITIALIZE INIT(0)
#define INIT(N) INIT_##N
#define INIT_0 whichCategory(0), INIT_1
#define INIT_1 whichCategory(1), INIT_2
//...
#define INIT_127 whichCategory(127)
我想要一种方法来填充此数组或包含该数组的结构,而无需此宏 hack...
可能是这样的
struct Table {
Type _[128];
};
constexpr Table table = MagicFunction();
那么,问题是如何写这个MagicFunction?
注意:我知道cctype和likes,这个问题更像是Is this possible?而不是Is this the best way to do it?。
任何帮助将不胜感激。
谢谢,
【问题讨论】:
-
你知道 ASCII 只在
[0 .. 127]范围内吗?char的签名是实现定义的吗?你目前的做法是非常危险的。哦,最后但同样重要的是,C++ 标准根本不需要 ASCII 编码。也可能是 EBCDIC。 -
好消息是,因为数组可以用包扩展来初始化,所以你要求的确实是可行的。您只需要多次调用该函数:p
-
@DyP:
((c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A))fromIsAlphabet-- 这假定了 ASCII 中存在的十进制顺序。签名很重要,因为 OP 传递文字> 127,它可能映射到负数chars。 -
@BeyondSora:对不起,我昨天没有时间正确解决这个问题。谢天谢地,Xeo 做到了(尽管他脾气暴躁:p)。索引生成与包扩展相结合是生成各种初始化列表的好方法(如您在此处看到的),因此我指出了这样一个事实,即由于数组接受初始化列表,所以您很出色。
-
@DyP:使用 EBCDIC,
0x41根本不会映射到任何符号,并且字母在代码页中的位置很奇怪。看看here。
标签: c++ templates c++11 constexpr