我使用googletest测试我的C ++代码。如果由于使用错误的索引访问vector::_M_range_check
而引发std::vector
异常,则googletest会报告:
C++ exception with description "vector::_M_range_check" thrown in the test body.
太好了,现在我也想知道哪个矢量,哪个指数和哪个范围。如何轻松获取此信息,将测试代码保留在googletest单元测试用例中?
(我几乎从Java开始很长一段时间IndexOutOfBoundsException ......)
答案 0 :(得分:8)
如果您使用此命令行选项运行,那么您的异常将一直冒出:
--gtest_catch_exceptions=0
在调试器内执行此操作将为您提供异常的堆栈跟踪。
答案 1 :(得分:7)
此处不涉及Google Test。您的C ++标准库实现引发了异常,并且由C ++标准库实现来决定如何使其例外变得冗长。
由于您收到异常,我认为您使用的是std::vector::at
而不是std::vector::operator[]
。您可以采取几种方法来获取更多信息。
首先,您可以通过调用at
替换对operator[]
的调用(个人而言,我发现at
的异常投掷范围检查非常有用,并且它确实有性能开销)并使用C ++标准库实现的迭代器调试。例如,使用g ++,如果我使用operator[]
并使用-D_GLIBCXX_DEBUG
进行编译以启用operator[]
的范围检查,则会出现类似于以下内容的错误:
/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_at
的来电:(未经测试)
template <typename T>
T& test_at(std::vector<T>& v, size_t n) {
// Use Google Test to display details on out of bounds.
// We can stream additional information here if we like.
EXPECT_LT(n, v.size()) << "for vector at address " << &v;
// Fall back to at, and let it throw its exception, so that our
// test will terminate as expected.
return v.at(n);
}
答案 2 :(得分:0)
vector::at(size_type n)
被记录为在无效out_of_range
(23.2.3p17)上投掷n
。 out_of_range
不包含有关容器或索引的信息,因此如果您需要该信息,则必须包装at
:
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));
}
}
};
请注意,at
不是虚拟的,因此您必须通过包装的at
进行调用以获取嵌套异常。