根据编译 switch/NDEBUG 在 std::vector 的 at() 和 operator[] 之间交换

Swap between at() and operator[] for std::vector depending on compile switch/NDEBUG

我知道 g++(和 MSVC)有允许对 operator[] 进行边界检查的开关,不幸的是,据我所知,LLVM 的 libc++ 没有此类开关或调试代码的完整实现。

在我当前的项目中,我一直在使用我自己的 vector 实现(几年前我为可移植性编写的),它不会抛出异常并且对 operator[] 和 at(实际上一个调用另一个,它们的行为完全相同,没有例外)。

我将在完成当前程序后移交此代码库,它可能会使用很长时间。因为我不应该被要求维护它或任何我宁愿在任何地方都完全符合标准而且我不认为重新实现一个容器符合标准的精神,(我也非常怀疑我的容器与 libc++ 或 libstdc++ 团队编写的一样好)。

是否有一些预处理器魔术或类似的东西可以让我在调试期间使 operator[] 表现得像 at() (因此它由于未捕获的异常而中止)并在我禁用此调试模式时表现得像 operator[] ? (项目完全支持 C++14)

我们从the trunk libc++ source code for vector可以看出,std::vector<>::operator[]里面确实有这样一个检查,经过_LIBCPP_ASSERT.

不幸的是,the libc++ debug feature is not yet functional

所以:

  • 注意 libc++ 更新
  • 训练您的团队期望 operator[] 默默地接受损坏的输入。根据定义,这就是它的作用。依赖特定于实现的额外健全性检查是一个非常糟糕的主意。如果您的团队不确定自己在做什么,他们应该编写自己的断言。

Is there some preprocessor magic or similar that I can do to make operator[] behave like at() during debug (so it aborts due to an uncaught exception) and behave like operator[] when I disable this debug mode? (Project is fully C++14 supported)

呃……这个怎么样?

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 相同,未定义宏时速度更快。