有一个作业问题我一直在破坏我的大脑:
我必须在 C++ 中创建一个数组类,其中在编译时检查对数组中元素的索引访问,即如果我尝试使用超出 ita 大小的索引访问数组,则会导致编译错误。
我以为我会使用枚举而不是整数作为索引,但我与我的导师交谈,他告诉我这不是正确的方法,他还说“认为以相同的价格你可以使用它来拥有一个数组,其中索引不是从 0" 或类似的东西开始的。
我会很感激任何建议!
std::array
来自 C++11 的正是您所要求的。它是一个编译时已知大小的数组,允许编译时检查越界错误
例子:
std::array<int, 5> arr = {1, 2, 3, 4, 5};
std::get<3>(arr); // returns 4;
std::get<9>(arr); // COMPILE ERROR
在内部,此数组是使用模板化数组大小实现的(如您从示例中看到的,第一行中的第二个模板参数),并static_assert
为您的条件执行编译时检查(在本例中为index < array_size
)。此外,正如您在示例中看到的,您使用 std::get 而不是 operator[],因为它再次使用模板化参数作为索引,它必须是一个常量表达式 ( constexpr
) 以允许编译时检查而不是运行时检查.
如果你需要一个变量索引,你可以使用旧的好的 operator[] 但你不会有编译时越界检查,这显然是不可能的。
这里有一个提示:如果你想在编译时检查值,你基本上只有一个选择:你需要使用非类型模板参数。
标准库类型std::tuple
实现了他的,因此请查看它以获取有关如何解决此问题的灵感。
一个提示,也许措辞有点不同:如果你想在编译时检查索引,它的值也必须在编译时知道。现在,如何在编译时将一些东西传递给一个函数?
在编译时发出错误信号,static_assert
可以相当容易地使用。
您可能有机会使用自定义类作为索引类型。然后,您可以通过限制类的运算符来限制索引元素的生成。特别是这可以确保没有用户输入可以用作索引(如果您不提供任何将整数(或类似)转换为索引类型的方法。如果您允许这样做,您根本没有机会!)。