C++ 中的编译时安全数组

compile-time safe array in C++?

本文关键字:安全 数组 编译 C++      更新时间:2023-10-16

有一个家庭作业问题

我一直在绞尽脑汁:

我必须在C++中创建一个数组类,其中在编译时检查对数组中元素的索引访问,即如果我尝试使用超出 ita 大小的索引访问数组,则会导致编译错误。

我以为我会使用枚举而不是整数作为索引,但我和我的老师交谈过,他告诉我这不是正确的方法,他还说"认为以相同的价格你可以使用它来拥有一个索引不从 0 开始的数组"或类似的东西。

我将不胜感激任何建议!

C++11 的std::array正是您所要求的。它是一个具有编译时已知大小的数组,它允许编译时检查越界错误

例:

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 ( 以允许编译时检查而不是运行时。

如果你需要一个变量索引,你可以使用旧的良好运算符[],但你不会有编译时越界检查,这显然是根本不可能的。

这里有一个提示:如果你想在编译时检查,你基本上只有一个选择:你需要使用非类型模板参数。

标准库类型std::tuple实现了他的问题,因此请查看它以获取有关如何解决此问题的灵感。

一个提示,可能措辞有点不同:如果要在编译时检查索引,则在编译时也必须知道其值。现在,如何在编译时将某些内容传递给函数?

为了在编译时发出错误信号,static_assert可以相当容易地使用。

您可能有机会使用自定义类作为索引类型。然后,可以通过限制类的运算符来限制索引元素的生成。特别是这可以确保没有用户输入可以用作索引(如果您不提供任何将整数(或类似(转换为索引类型的方法。如果你允许这样做,你根本没有机会!