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

时间:2013-06-25 12:04:50

标签: c++ templates

这个功课问题我一直在破坏我的大脑:

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

我以为我会使用枚举作为索引而不是整数,但我跟我的导师谈过,他告诉我这不是正确的方法,他还说“认为以相同的价格你可以用这个来索引不以0“开头的数组或类似的东西。

我很感激任何建议!

4 个答案:

答案 0 :(得分:6)

来自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执行,对您的条件执行编译时检查(在这种情况下,它将是{ {1}})。另外正如您在示例中看到的那样,您使用的是std :: get而不是operator [],因为它再次使用模板化参数作为索引,它必须是一个常量表达式(index < array_size)以允许编译时检查而不是运行时。

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:1)

一个提示,或许措辞有点不同:如果你想在编译时检查索引,它的值也必须在编译时知道。现在,如何在编译时

传递一些函数,比如一个函数?

要在编译时发出错误信号,static_assert可以很容易地使用。

答案 3 :(得分:0)

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