根据编译开关/NDEBUG,在std::vector的at()和操作符[]之间进行交换
Swap between at() and operator[] for std::vector depending on compile switch/NDEBUG
我知道g++(和MSVC)有允许对操作符[]进行边界检查的开关,不幸的是,据我所知,LLVM的libc++没有完整的实现这种开关或调试代码。
在我目前的项目中,我一直在使用我自己的vector实现(我几年前为可移植性写的),它不会抛出异常,并且对operator[]和at(实际上一个调用另一个并且它们的行为相同,因为没有异常)具有基于断言的边界检查。
我将在完成当前程序后移交这个代码库,它可能会使用很长一段时间。因为我不应该被要求维护它或任何东西,我宁愿在任何地方都完全符合标准,我不认为重新实现容器符合标准的精神,(我也高度怀疑我的容器是否像libc++或libstdc++团队写的那样好)。
是否有一些预处理器魔法或类似的,我可以做使operator[]在调试期间表现得像at()(因此它由于未捕获的异常而中止),并在禁用此调试模式时表现得像operator[] ?(项目完全支持c++ 14)
我们可以从vector的主干libc++源代码中看到,在std::vector<>::operator[]
中确实有这样一个检查,它经过_LIBCPP_ASSERT
。
不幸的是,libc++调试特性还不能使用。
:
- 关注libc++的更新
- 训练你的团队期望
operator[]
默默接受损坏的输入。根据定义,这就是它的作用。依赖于特定于实现的额外的完整性检查是一个非常糟糕的主意。如果你的团队不确定他们在做什么,他们应该写自己的断言。
是否有一些预处理器魔法或类似的,我可以做使operator[]在调试期间表现得像at()(因此它由于未捕获的异常而中止),并在禁用此调试模式时表现得像operator[] ?(项目完全支持c++ 14)
呃…这个怎么样?
const T& your_vector::operator[](std::size_t index) const
{
#ifndef NDEBUG // !! double negative condition
if(index >= size_) // assume size_ is std::size_t size_; member of class
throw std::out_of_bounds{"const T& your_vector::operator[]"};
#endif
return data_[index]; // assume data_ is a native array containing the elements
}
const T& your_vector::at(std::size_t index) const
{
if(index >= size_) // assume size_ is std::size_t size_; member of class
throw std::out_of_bounds{"const T& your_vector::at"};
return data_[index]; // assume data_ is a native array containing the elements
}
在定义DEBUG时,索引操作符的实现与at
相同,在未定义宏时更快。
相关文章:
- C++嵌套if语句,基本货币交换
- shell排序中的交换和比较
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 通过交换元素使数组相同
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- 交换运算符 + 重载会导致无限递归
- 为什么 std::reduce 需要交换性?
- 复制和交换习惯用法与移动操作之间的交互
- C++ - 没有自定义交换功能的移动分配运算符?
- 如何在数组中交换最小和最大的位置?
- 尽管一切看起来都很好,但值不会交换
- C++交换来自同一类成员的参数值,处理多个类
- 插入排序的最小交换
- C++在 2 个向量向量之间交换向量
- 转置矩阵:交换元素不会更改值
- 不正确的比较和交换计数器输出用于快速排序功能
- 交换函数不是在 C++ 中交换 2D 数组的元素
- 移动构造函数和赋值操作符,使用复制-交换习惯实现
- 根据编译开关/NDEBUG,在std::vector的at()和操作符[]之间进行交换
- 复制和交换技术在赋值操作符函数内部使用复制构造函数