在 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++ 中不起作用,因为嵌套数组指示符不是该语言的一部分。我可以想到上面代码的两个工作替代方案,但都有缺点:

  1. 只是不要使用指示符来初始化数组中的条目。这大大降低了它的可读性,因为我无法一眼看出哪个条目对应于哪个标记。 add/remove 令牌或修复错误的初始化也会很烦人。
private:
    static constexpr bool m_grammar_allowed[NUMBER_OF_TOKEN_KINDS][NUMBER_OF_TOKEN_KINDS] = {
        {false, true, true, false, false, true, ...},
        ...
    }
  1. 在构造函数中逐行初始化条目。这不会失去可读性但速度较慢,因为数据必须在运行时加载而不是存储在可执行文件本身中。
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();