在 C++ 中用于初始化二维数组的 C 嵌套数组指示符的最佳替代方法是什么?
What is the best alternative to C's nested array designators in C++ for initializing a 2D array?
我目前正在尝试将我的小型正则表达式引擎从 C 转换为 C++。
为了以一种紧凑的方式丢弃语法上不正确的正则表达式,我使用一个二维数组来定义一个接一个地允许使用哪些类型的标记:
#define NUMBER_OF_TOKEN_KINDS 15
typedef enum {
Literal,
Alternator,
...
} TokenKind;
bool grammar_allowed[NUMBER_OF_TOKEN_KINDS][NUMBER_OF_TOKEN_KINDS] = {
...
[Literal][Alternator] = true,
[Alternator][Literal] = true,
...
}
使用这种结构,您可以通过检查是否设置了 grammar_allowed[previous_token][current_token]
来轻松捕获大部分语法错误。
这种初始化方式 grammar_allowed
在 C++ 中不起作用,因为嵌套数组指示符不是该语言的一部分。我可以想到上面代码的两个工作替代方案,但都有缺点:
- 只是不要使用指示符来初始化数组中的条目。这大大降低了它的可读性,因为我无法一眼看出哪个条目对应于哪个标记。 add/remove 令牌或修复错误的初始化也会很烦人。
private:
static constexpr bool m_grammar_allowed[NUMBER_OF_TOKEN_KINDS][NUMBER_OF_TOKEN_KINDS] = {
{false, true, true, false, false, true, ...},
...
}
- 在构造函数中逐行初始化条目。这不会失去可读性但速度较慢,因为数据必须在运行时加载而不是存储在可执行文件本身中。
Lexer() {
...
m_grammar_allowed[Literal][Alternator] = true;
m_grammar_allowed[Alternator][Literal] = true;
...
}
有没有其他方法可以在 C++ 中像这样初始化二维数组,但又不牺牲可读性或性能?
谢谢!
您可以创建一个 constexpr 函数来初始化您的 std::array
(而不是 C 数组):
constexpr
std::array<std::array<bool, NUMBER_OF_TOKEN_KINDS>, NUMBER_OF_TOKEN_KINDS>
make_grammar_allowed()
{
std::array<std::array<bool, NUMBER_OF_TOKEN_KINDS>, NUMBER_OF_TOKEN_KINDS> res {};
res[Literal][Alternator] = true;
res[Alternator][Literal] = true;
// ...
return res;
}
和
static constexpr
std::array<std::array<bool, NUMBER_OF_TOKEN_KINDS>, NUMBER_OF_TOKEN_KINDS>
m_grammar_allowed = make_grammar_allowed();
我目前正在尝试将我的小型正则表达式引擎从 C 转换为 C++。 为了以一种紧凑的方式丢弃语法上不正确的正则表达式,我使用一个二维数组来定义一个接一个地允许使用哪些类型的标记:
#define NUMBER_OF_TOKEN_KINDS 15
typedef enum {
Literal,
Alternator,
...
} TokenKind;
bool grammar_allowed[NUMBER_OF_TOKEN_KINDS][NUMBER_OF_TOKEN_KINDS] = {
...
[Literal][Alternator] = true,
[Alternator][Literal] = true,
...
}
使用这种结构,您可以通过检查是否设置了 grammar_allowed[previous_token][current_token]
来轻松捕获大部分语法错误。
这种初始化方式 grammar_allowed
在 C++ 中不起作用,因为嵌套数组指示符不是该语言的一部分。我可以想到上面代码的两个工作替代方案,但都有缺点:
- 只是不要使用指示符来初始化数组中的条目。这大大降低了它的可读性,因为我无法一眼看出哪个条目对应于哪个标记。 add/remove 令牌或修复错误的初始化也会很烦人。
private:
static constexpr bool m_grammar_allowed[NUMBER_OF_TOKEN_KINDS][NUMBER_OF_TOKEN_KINDS] = {
{false, true, true, false, false, true, ...},
...
}
- 在构造函数中逐行初始化条目。这不会失去可读性但速度较慢,因为数据必须在运行时加载而不是存储在可执行文件本身中。
Lexer() {
...
m_grammar_allowed[Literal][Alternator] = true;
m_grammar_allowed[Alternator][Literal] = true;
...
}
有没有其他方法可以在 C++ 中像这样初始化二维数组,但又不牺牲可读性或性能?
谢谢!
您可以创建一个 constexpr 函数来初始化您的 std::array
(而不是 C 数组):
constexpr
std::array<std::array<bool, NUMBER_OF_TOKEN_KINDS>, NUMBER_OF_TOKEN_KINDS>
make_grammar_allowed()
{
std::array<std::array<bool, NUMBER_OF_TOKEN_KINDS>, NUMBER_OF_TOKEN_KINDS> res {};
res[Literal][Alternator] = true;
res[Alternator][Literal] = true;
// ...
return res;
}
和
static constexpr
std::array<std::array<bool, NUMBER_OF_TOKEN_KINDS>, NUMBER_OF_TOKEN_KINDS>
m_grammar_allowed = make_grammar_allowed();