12

使用 stl::vector:

vector<int> v(1);
v[0]=1; // No bounds checking
v.at(0)=1; // Bounds checking

有没有办法禁用边界检查而不必全部重写at()[]?我正在使用 GNU 标准 C++ 库。

编辑:我改为at()[]我怀疑存在瓶颈的区域,它显着减少了计算时间。但是,由于我在开发代码和运行实验之间进行迭代,我想在开发期间启用边界检查,并在我真正运行实验时禁用它。我想安德鲁的建议是最好的解决方案。

4

8 回答 8

25

如果您真的想这样做(至少对于快速而肮脏的分析比较),如果您没有其他at()s ,这将起作用

#define at(x) operator[](x)

如果您想保留at()用于开发和operator[]生产中使用,只需将其包装在#ifdef.

如果您确实有其他at()s,您可以随时编辑您的#included<vector>文件。

于 2010-03-05T07:37:08.017 回答
15

不。 的边界检查std::vector::at由标准指定,并且没有符合标准的 C++ 实现可以偏离该标准。

于 2010-03-05T03:18:37.167 回答
6

也许更好的解决方案是使用[]和使用标准库的检查实现进行调试。

于 2010-03-05T03:35:26.400 回答
5

根据您想要打开/关闭边界检查的评论,您可以使用包装模板功能:

template <class T>
inline typename T::reference deref(T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

template <class T>
inline typename T::const_reference deref(const T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

您必须修改您的代码以启用此功能,但是一旦您将其安装到位,您就可以根据需要打开或关闭绑定检查。

我承认它看起来有点难看:

deref(vec, 10) = ...;
于 2010-03-05T08:12:14.593 回答
3

不是标准方式。您可以在编译器中关闭异常。你可以用 gcc 和-fno-exceptions.

不过,您应该警惕这样做;您的库(包括标准库)在关闭异常的情况下可能无法正常运行。检查您的文档,以及gcc 邮件列表中类似的主题。

于 2010-03-05T03:18:47.980 回答
3

at()当您总是想要检查时使用。另请注意,这会在错误时引发异常,因此它可能是可恢复的。如果您想要更快的、未经检查的访问器,请使用[],但是应该彻底测试使用它的算法,因为故障模式更严重(未定义的行为)。

[]在 Linux 上使用 GCC 时检查开发模式边界的几种方法:

其他一些有趣的讨论:vector::at vs.vector::operator[]

于 2015-12-26T02:21:10.413 回答
2

在您自己的命名空间中派生您自己的向量类,例如“uncheckedvector”,并覆盖基本向量类型的 at() 以使用数组索引。

然后使用“使用 uncheckedvector::vector”将让你在任何地方覆盖你对矢量的所有使用。但是,如果您在任何地方使用完全限定的类型,这将不起作用。

于 2010-03-05T08:17:11.923 回答
0

如果您有相当一致的访问模式(即/不是随机访问),而不是使用at()or [],避免范围检查的一种方法是使用迭代器,使用begin(), end()advance()甚至更好,通过使用标准算法。

尽管这并不能解决纠正at()范围检查的潜在问题,但标准库 (MSVC) 的某些实现已经检查了某些类型构建的迭代器

于 2010-03-05T08:11:11.140 回答