【问题标题】:compile-time safe array in C++?C ++中的编译时安全数组?
【发布时间】:2013-06-25 12:04:50
【问题描述】:

我一直在思考这个家庭作业问题:

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

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

如果有任何建议,我将不胜感激!

【问题讨论】:

  • 你不可能在使用变量完成索引的地方报告这样的错误,因为很可能它的值只有在运行时才知道。

标签: c++ templates


【解决方案1】:

来自 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 &lt; array_size )。此外,正如您在示例中看到的那样,您使用 std::get 而不是 operator[],因为它再次使用模板化参数作为索引,它必须是一个常量表达式 (constexpr) 以允许编译时检查而不是运行时。

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

【讨论】:

  • 很好,但没有真正解释如何创建这样的类。
  • 我加了一点解释
  • 谢谢!但我很确定我不能使用 static_assert 因为它几乎完全符合我自己的预期
  • @dog 实现你自己的static_assert 是一个完全不同的故事,至少需要一些 TMP 摆弄。
【解决方案2】:

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

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

【讨论】:

  • 一般来说你的第一句话不是真的 - 你也可以使用带有 constexpr 值的 static_assert。
  • @sasha.sochka 当然。我是在运行时调用函数并将参数传递参​​数 的上下文中编写的。 constexpr 如果允许在函数参数上使用,它将起作用。
  • 这是允许的。简单示例:constexpr int sqr(int val) { return val * val; } int arr[sqr(3)];
  • @sasha.sochka 又太仓促了。当然可以。但是sqr 不能是对非constexpr 对象进行操作的成员函数。
  • Ehhm,也许这在原始问题的上下文中不再有意义,但您可以使 sqr 成为在非 constexpr 对象上运行的成员函数(显然返回非 constexpr)
【解决方案3】:

一个提示,也许措辞有点不同:如果你想在编译时检查索引,它的值也必须在编译时知道。现在,如何在编译时向函数传递一些东西?

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 我认为这就是他的意思,但我不知道如何创建一个具有有限代数的类(编译器以某种方式知道的数字?)这是从讲座幻灯片中引用的:“数组引用:不可能检测到数组索引的溢出。当索引是整数类型时是不可能的 - 如果索引的类型对应于数组大小(它必须是数组类型的一部分),则不是。”
    • 您的演讲幻灯片中的引述让我想到一个假设,即模板驱动的解决方案可能是预期的(正如@sasha_sochka 指出的那样)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多