[英]Why is my out_of_range exception not being caught
我是 cpp 的新手,我正在尝试几件事。 这个我自己好像也搞不明白。
#include <cstdio>
#include <stdexcept>
template <class E, class V>
struct Pair {
E first;
V second;
Pair(E fst, V snd) : first(fst), second(snd) {}
E getFirst() { return first; }
V getSecond() { return second; }
};
template <class t, unsigned dim>
struct vec {
t d[dim];
static constexpr int dimen = dim;
t &operator[](unsigned n) {
std::printf("dim: %d %d\n", dim, n);
if (n >= dim) {
std::printf("checking %d\n", n);
throw std::out_of_range("vector index is out of range");
}
return d[n];
};
};
int main() {
try {
Pair<int, vec<int, 2> *> test2(2, new vec<int, 2>{1, 2});
std::printf("%d\n", test2.getSecond()->dimen);
std::printf("before\n");
std::printf("%d\n", test2.getSecond()->d[2]); // it seems like the compiler kind of ignores this
} catch (std::out_of_range e) {
std::printf("Caught!!");
}
return 0;
}
现在,行std::printf("%d\n", test2.getSecond()->d[2]);
理想情况下应该抛出 out_of_range 错误,但事实并非如此。 我的 linter 实际上警告我这也超出了范围。 我可以编译并运行该程序,它会返回一些垃圾0
值。
我的问题是:为什么错误没有被抛出或错误没有被捕获? 我认为错误没有被抛出,因为我运行它时没有打印检查。
因为实际上从未达到throw
代码。
在此行中:
std::printf("%d\n", test2.getSecond()->d[2]);
getSection()
返回指向vec
object 的指针。 然后,当您执行->d
时,您正在访问vec
object 中的d
数组。 因此,当您将[2]
添加到末尾时,您正在访问数组索引 2 处的元素,而不是调用vec
object 的operator[]
。
如果你这样重写:
std::printf("%d\n", (*test2.getSecond())[2]);
然后将在vec
object 上调用operator[]
,而不是它的数组。 请注意,您必须取消引用getSecond()
的结果。 或者,您可以更详细:
std::printf("%d\n", test2.getSecond()->operator[](2));
非常好的问题!
问题是当您尝试通过索引引用数组中的项目时,例如 [2],您实际上是在引用 size * 2 位置。 没有针对它的内置保护,但您始终可以检查 \0 因为这是您的 arrays 结束的地方。 当您在 C/C++ 中使用 arrays 时,您的工作是确保您不在他们的位置之外。 将数组保留在结构/类中并允许使用 setter 和 getter 访问其元素通常是一个好主意,这将处理边界并在违反这些边界时抛出异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.