std::array 中的编译时间范围检查

ski*_*ris 5 c++ g++ stdarray

我想在编译时对 std::array 执行范围检查。下面是一个例子:

#include <iostream>
#include <array>

void rarelyUsedFunction(const std::array<double, 2>& input)
{
    std::cout << input[5] << std::endl;
}

int main()
{
    std::array<double, 2> testArray;
    rarelyUsedFunction(testArray);
}
Run Code Online (Sandbox Code Playgroud)

如果我用 g++ 编译它,则没有警告或错误,尽管对不在数组中的元素进行了未定义的访问。编译后的程序只是打印一些随机值。

g++ 中是否有编译器选项可用于在编译时执行的合适的范围/边界检查?我知道我可以添加“-D_GLIBCXX_DEBUG”,但这只会在运行时执行检查。如果我有一个不经常调用的函数,则不会触发。

我知道,不能在所有情况下都执行这样的范围检查,但在上述情况下,编译器应该能够发现问题!?

小智 5

正如评论中提到的,std::get(std::array)这会很好地为你做,因为它有义务进行这样的边界检查:

I 必须是 [0, N) 范围内的整数值。这是在编译时强制执行的,而不是 at() 或运算符[]。

在您的示例中,它看起来像这样:

void rarelyUsedFunction(const std::array<double, 2>& input)
{
    std::cout << std::get<5>(input) << std::endl; // <---- Compilation error!
}
Run Code Online (Sandbox Code Playgroud)

如果索引不仅仅是一个文字,只要您设法将其填充到变量中,您仍然可以使用“复杂”代码来计算它constexpr

void rarelyUsedFunction(const std::array<double, 2>& input)
{
    constexpr std::size_t index = /* Whatever, as long as it compiles... */;
   
    std::cout << std::get<index>(input) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

显然,无论哪种情况,这都涉及向编译器提供索引在编译时已知的硬保证。