我知道g ++(和MSVC)具有允许对operator []进行边界检查的开关,遗憾的是,据我所知,LLVM的libc ++并没有完全实现这样的开关或调试代码。
在我当前的项目中,我一直在使用我自己的vector实现(几年前我写的可移植性),它不会抛出异常,并且对operator []和(实际上)有基于断言的边界检查一个调用另一个,它们的行为相同,因为没有例外)。
在我完成当前程序后,我将会移交此代码库,并且可能会在很长一段时间内使用。由于我不应该被要求维护它或任何我想在任何地方完全符合标准,我不觉得重新实施容器是符合标准的精神,(我也高度怀疑我的容器和libc ++或libstdc ++团队编写的容器一样好。
我是否可以使用一些预处理器魔法或类似物来使operator []在调试期间表现得像at()因为未捕获的异常导致中止(并且当我禁用此调试模式时,它的行为类似于operator [])? (项目完全支持C ++ 14)
答案 0 :(得分:7)
我们可以从the trunk libc++ source code for vector看到std::vector<>::operator[]
内确实有这样的检查,通过_LIBCPP_ASSERT
。
不幸的是,the libc++ debug feature is not yet functional。
所以:
operator[]
默默接受损坏的输入。根据定义,这就是它的作用。依赖于特定于实现的附加健全性检查是一个非常糟糕的主意。如果他们不确定他们在做什么,你的团队应该写自己的断言。答案 1 :(得分:-1)
我是否可以使用一些预处理器魔法或类似物来使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
相同,未定义宏时更快。