使用stl :: vector:
vector<int> v(1);
v[0]=1; // No bounds checking
v.at(0)=1; // Bounds checking
有没有办法禁用边界检查而不必将所有at()
重写为[]
?我正在使用GNU标准C ++库。
修改:我在怀疑存在瓶颈的区域将at()
更改为[]
,这大大缩短了计算时间。但是,由于我在开发代码和运行实验之间进行迭代,我想在开发过程中启用边界检查,并在运行实验时禁用它。我想安德鲁的建议是最好的解决方案。
答案 0 :(得分:24)
如果您真的想这样做(至少对于快速和脏的分析比较),如果您没有其他at()
#define at(x) operator[](x)
如果您想保留at()
进行开发并在生产中使用operator[]
,只需将其打包在#ifdef
中。
如果您有其他at()
,则可以随时修改#include
d <vector>
个文件。
答案 1 :(得分:15)
没有。 std::vector::at
的边界检查由标准指定,并且没有符合标准的C ++实现可能与此不同。
答案 2 :(得分:6)
也许更好的解决方案是使用[]
并使用标准库的已检查实现进行调试。
答案 3 :(得分: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) = ...;
答案 4 :(得分:3)
不是标准方式。您可以关闭编译器中的异常。您可以使用带有-fno-exceptions
的gcc执行此操作。
你应该警惕这样做;您的库(包括标准库)可能无法正常关闭异常。检查您的文档以及this one on the gcc mailing list。
等主题答案 5 :(得分:2)
在您自己的命名空间中导出您自己的矢量类,如“uncheckedvector”,并覆盖基矢量类型的at()以使用数组索引。
然后使用“使用uncheckedvector :: vector”将允许您覆盖所有向量的使用。 如果您在任何地方使用完全限定类型,这将无效。
答案 6 :(得分:2)
当始终想要检查时,请使用at()
。另请注意,这会在出错时抛出异常,因此可能会被恢复。如果你想要更快,未经检查的访问者,请使用[]
,但是应该彻底测试使用它的算法,因为失败模式更严重(未定义的行为)。
在Linux上使用GCC时,有两种开发模式边界检查[]
的方法:
启用GCC debug mode,另请参阅GCC STL bound checking
-D_GLIBCXX_DEBUG
在Valgrind内存检查器
下运行您的程序 valgrind (your program and args)
其他一些有趣的讨论:vector::at vs. vector::operator[]
答案 7 :(得分:0)
如果您具有合理一致的访问模式(即/非随机访问),而不是使用at()
或[]
,则避免范围检查的一种方法是使用begin()
使用迭代器,end()
和advance()
甚至更好,通过使用标准算法。
虽然这不能解决纠正at()
进行范围检查的根本问题,但标准库(MSVC)的某些实现已经检查了某些类型的构建的迭代器