Google测试和std::向量范围异常 我用GooGestEST测试我的C++代码。当由于使用错误索引访问std::vector而引发vector::\u M\u range\u check异常时,Google测试报告: C++ exception with description "vector::_M_range_check" thrown in the test body.

Google测试和std::向量范围异常 我用GooGestEST测试我的C++代码。当由于使用错误索引访问std::vector而引发vector::\u M\u range\u check异常时,Google测试报告: C++ exception with description "vector::_M_range_check" thrown in the test body.,c++,exception,vector,googletest,C++,Exception,Vector,Googletest,很好,现在我还想知道哪个向量,哪个索引,哪个范围。我怎样才能轻松获得这些信息,将测试代码保存在googletest单元测试用例中 (我几乎开始渴望Java,因为它有着很好的历史…这里没有涉及谷歌测试。C++标准库实现正在抛出异常,这取决于C++标准库实现来决定如何使其异常。< /P> 由于您得到了一个异常,我假设您使用的是std::vector::at而不是std::vector::operator[]。有几种可能的方法可以让你获得更多的信息 首先,可以在调用运算符[]/COD>时,在< /CO

很好,现在我还想知道哪个向量,哪个索引,哪个范围。我怎样才能轻松获得这些信息,将测试代码保存在googletest单元测试用例中


(我几乎开始渴望Java,因为它有着很好的历史…

这里没有涉及谷歌测试。C++标准库实现正在抛出异常,这取决于C++标准库实现来决定如何使其异常。< /P> 由于您得到了一个异常,我假设您使用的是
std::vector::at
而不是
std::vector::operator[]
。有几种可能的方法可以让你获得更多的信息

首先,可以在调用<代码>运算符[]/COD>时,在< /COD>中调用<代码> >(个人,我不在< /COD>异常抛出范围检查中找到<代码>,它非常有用,并且它确实有性能开销),并使用C++标准库实现的迭代器调试。例如,在g++中,如果我使用

运算符[]
并使用
-D_GLIBCXX_DEBUG
编译以启用
运算符[]
的范围检查,我会得到类似以下错误:

/usr/include/c++/4.3/debug/vector:237:error: attempt to subscript container
    with out-of-bounds index 0, but container only holds 0 elements.
其次,您可以将对
at
的调用替换为对
test\u at
的调用或类似的调用:(未测试)

模板
测试和测试(标准:向量和v,尺寸){
//使用谷歌测试显示越界的详细信息。
//如果愿意,我们可以在这里传输附加信息。

如果使用此命令行选项运行,则您的异常将一直冒泡:

--gtest_catch_exceptions=0
在调试器内部执行此操作将为您提供异常的确切堆栈跟踪。

向量::at(大小类型n)
记录为在无效
n
上抛出
超出范围(23.2.3p17).
out\u of_range
不包含容器或索引上的信息,因此如果需要该信息,您必须将
包装在
处:

template<typename T> struct my_vector: public std::vector<T> {
  using std::vector<T>;
  struct at_out_of_range: public std::out_of_range {
    my_vector *vector;
    size_type size;
    size_type n;
    at_out_of_range(my_vector *vector, size_type size, size_type n):
      std::out_of_range("at_out_of_range"), vector(vector), size(size), n(n) {}
  };
  reference at(size_type n) {
    try {
      return std::vector<T>::at(n);
    } catch(std::out_of_range &ex) {
      std::throw_with_nested(at_out_of_range(this, size(), n));
    }
  }
};
template struct my_vector:public std::vector{
使用std::vector;
位于\u out\u of \u范围的结构:public std::out\u of \u范围{
我的向量*向量;
大小\类型大小;
n型尺寸;
在范围外(我的向量*向量,大小类型大小,大小类型n):
std::out_of_range(“at_out_of_range”)、向量(vector)、大小(size)、n(n){
};
参考(尺寸\类型n){
试一试{
返回std::vector::at(n);
}捕获(标准:超出范围和ex){
std::抛出带有嵌套的_(在_超出_范围(this,size(),n));
}
}
};

请注意,
at
不是虚拟的,因此必须通过包装的
at
调用以获取嵌套异常。

--gtest\u catch\u exceptions=0@JaredC该标志在抛出异常后终止测试,但输出不提供有关异常来源(向量、索引、范围)的更多信息@cls:如果您在调试器中运行测试,或者在终止后检查核心转储,那么您应该看到未处理的异常是从何处引发的。或者,您可以在
std::\uu throw\u out\u of_range
上设置断点,这是GNU库调用的抛出异常的函数。对,但不是索引和边界e错误原因。@cls调试程序停止后,信息随时可用。
template<typename T> struct my_vector: public std::vector<T> {
  using std::vector<T>;
  struct at_out_of_range: public std::out_of_range {
    my_vector *vector;
    size_type size;
    size_type n;
    at_out_of_range(my_vector *vector, size_type size, size_type n):
      std::out_of_range("at_out_of_range"), vector(vector), size(size), n(n) {}
  };
  reference at(size_type n) {
    try {
      return std::vector<T>::at(n);
    } catch(std::out_of_range &ex) {
      std::throw_with_nested(at_out_of_range(this, size(), n));
    }
  }
};