在 std::vector 中自动检查边界

Automatically check bounds in std::vector

在积极开发使用 std::vector 的 class 期间,经常会发生索引越界的情况。 (有关实际示例,请参阅 this code review question。)使用 operator[] 时,这会导致未定义的行为。不过,[] 语法易于阅读,比编写 .at().

更方便

因此我想使用 [] 运算符编写我的代码,但同时启用了边界检查。测试代码后,删除边界检查应该很容易。

我在想下面的代码:

util::bound_checked<std::vector<int>> numbers;

numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
numbers.push_back(4);
std::cout << numbers[17] << "\n";

对我来说,这个实用程序模板似乎非常简单,我希望它存在。可以?如果有,用什么名字?

我认为不存在这样的东西,但创建它相当容易:

template <class Container>
struct bound_checked : public Container
{
  using Container::Container;

  auto operator[] (typename Container::size_type i) -> decltype(this->at(i))
  { return this->at(i); }

  auto operator[] (typename Container::size_type i) const -> decltype(this->at(i))
  { return this->at(i); }
};

[Live example]

请注意,上面实际上使用了一种不鼓励的做法,即public继承自标准容器(不是为其设计的)。我对您的问题的理解是,此包装器仅用于测试目的,这很好。但是,如果您希望它保留在生产环境中 并且 想要非常安全,请使用非 public 继承:

template <class Container>
struct bound_checked : private Container
{
  using Container::Container;

  auto operator[] (typename Container::size_type i) -> decltype(this->at(i))
  { return this->at(i); }

  auto operator[] (typename Container::size_type i) const -> decltype(this->at(i))
  { return this->at(i); }

  using Container::begin;
  using Container::end;
  using Container::at;
  using Container::insert;
  // ... you get the idea
};

Does it? If so, under which name?

我很确定它确实存在。如果启用了编译器内部 __DEBUG 构建宏,许多编译器会启用 std::vector<T>::at() 作为 std::vector::operator[]() 的实现。

Therefore I'd like to write my code using the [] operator, but at the same time have bounds checks enabled. After testing the code, it should be very easy to remove the bounds checks.

关于命名,我认为是 debugrelease 构建。在没有 __DEBUG 定义的情况下编译代码时将删除检查。

如果您使用 GCC(可能是 MinGW), Clang 与 libstdc++(GCC 的标准库),那么 #define _GLIBCXX_DEBUG 会做您想要的。

或者更好的是,用标志定义它:-D_GLIBCXX_DEBUG.

或者,还有 _GLIBCXX_ASSERTIONS,它执行较少的检查,但编译(并且可能运行)更快。

To me, this utility template seems to be so straight-forward that I'd expect it to exist

对于 gcc,它确实存在。 gcc libstdc++ 有一组调试容器。 std::vector 它有 __gnu_debug::vector 调试容器。参见 documentation