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

Rol*_*lig 11 c++ stdvector undefined-behavior

在使用的类的主动开发期间std::vector,通常会发生索引超出范围.(有关实际示例,请参阅此代码复习问题.)使用时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";
Run Code Online (Sandbox Code Playgroud)

对我来说,这个实用程序模板似乎是如此简单,我希望它存在.可以?如果是这样,以哪个名字?

Rei*_*ica 7

我不认为这样的事情存在,但创建相当容易:

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); }
};
Run Code Online (Sandbox Code Playgroud)

[实例]

请注意,上面实际上使用了一种不鼓励的做法,即从标准容器(不是为它设计)的公共继承.我对你的问题的理解是这个包装器只能用于测试目的,这很好.但是,如果您希望将其保留在生产环境中希望处于非常安全的一面,请使用非公共继承:

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
};
Run Code Online (Sandbox Code Playgroud)

  • @super是的,`std`容器不用于公共继承.如果您愿意,可以私下继承并使用`using`声明填充该类.我的印象是,这应该仅用于测试,并且从最终代码中删除了此类的使用.不过,我会在答案中添加免责声明. (2认同)

ks1*_*322 4

对我来说,这个实用程序模板似乎非常简单,我希望它存在

对于 gcc 来说它确实存在。gcc libstdc++ 有一组调试容器。因为std::vector它有__gnu_debug::vector调试容器。请参阅文档