如何使C++ Package 器为std::vector在终端上的超出范围消息提供文件和行信息并中止?
我写了附加的代码,它完成了这项工作,但需要额外的模板R,它是用来输出的结果,让它编译。
两个问题:
1.有什么方法可以避免使用宏来获取文件和行信息,这样就可以输出了?
1.有没有办法改变它,这样我就可以改变,使函数返回的项目?即std::string s = vec_get(v,idx);
这是当前输出,比stl_vector. h_M_range_check输出(这是STL库)更清晰
$ ./vec_throw2
vec_throw2.cpp:69 err std::vector 0 out of range size 0
terminate called after throwing an instance of 'std::out_of_range'
what(): vec_get
Aborted (core dumped)
The code follows
// g++ -Wall -O2 -o vec_throw vec_throw2.cpp
#include <vector>
#include <cstdio>
#include <stdexcept>
using namespace std;
template<class T, class R>
void vec_get(T v, R r, size_t idx, const char * const file, const int line)
{
if (idx<v.size())
{
r = v.at(idx);
}
else
{
printf("%s:%d err std::vector %zu out of range size %zu\n", file, line, idx, v.size());
throw std::out_of_range ("vec_get");
}
}
#define VEC_GET2(v, w, idx) vec_get(v, w, idx, __FILE__, __LINE__)
int main()
{
std::vector<std::string> v;
int ret = 0;
size_t idx = 0;
std::string s;
VEC_GET2(v, s, idx);
return ret;
}
我尝试了一些不同的方法,包括“自动”返回。
2条答案
按热度按时间dgtucam11#
使用
std::source_location
并只检查一次边界:可能的输出:
kfgdxczn2#
在c++20中,你可以使用
std::source_location
。虽然afaik只支持gcc
。这样你就不需要宏了。其实我不知道你在返回元素的时候遇到了什么问题,你可以这样做;)
Live Demo
正如在注解中提到的,一旦你检查了索引是有效的并且抛出了你自己的异常,那么调用
at
就没有意义了。另外,如果你还想在程序终止时看到输出,你必须确保在抛出异常之前刷新流。然而,我允许自己质疑你的方法,而不是习惯于尝试通过无效的索引访问元素,在实际访问元素之前,你应该确保索引是有效的。2你不能做到这一点的情况非常罕见。3在我的脑海中,我能想象的唯一的例子是当索引来自外部输入时。在这种情况下,您将对输入执行一些健全性检查,而不是依赖容器抛出一些
out_of_range
错误,这些错误对根本原因一无所知。另一方面,在很多情况下,你不需要边界检查,例如,在一个迭代元素的循环中,这将是一种浪费: