首页 > 解决方案 > 为什么我的 out_of_range 异常没有被捕获

问题描述

我是 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值。

我的问题是:为什么错误没有被抛出错误没有被捕获?我认为错误没有被抛出,因为我运行它时没有打印检查。

标签: c++templateserror-handling

解决方案


因为throw代码从未真正到达过。

在此行中:

std::printf("%d\n", test2.getSecond()->d[2]);

getSection()返回一个指向vec对象的指针。当您这样做时,->d您正在对象内访问d数组vec。因此,当您添加[2]到末尾时,您访问的是数组索引 2 处的元素,而不是调用operator[]vec对象。

如果你这样重写:

std::printf("%d\n", (*test2.getSecond())[2]);

然后operator[]将在vec对象上调用,而不是它的数组。请注意,您必须取消引用getSecond(). 或者,您可以更详细:

std::printf("%d\n", test2.getSecond()->operator[](2));

工作示例:https ://godbolt.org/z/YWKzPz


推荐阅读