为什么C++的例外不提供调用细节?

sta*_*low 16 c++

#include <fstream>
#include <iostream>
#include <map>

int main(int argc, char** argv) {
    try {
        std::map<std::string, int> m{{"a", 1}, {"b", 2}};
        std::cout << m.at("c") << std::endl;
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在C++中,当检索映射的不存在的键时,异常看起来像map::at: key not found.没有提供关于密钥的信息.

此外,如果正在访问不存在的文件,则会出现std::ios_base::failure类似的异常消息ios_base::clear: unspecified iostream_category error.未提供导致异常的文件名.因此,如果项目中有许多map.at()ifstream is用途,可能需要花费很长时间才能找出异常的来源.

与此相反,Python可能会告诉你KeyError: 'c'FileNotFoundError: [Errno 2] No such file or directory: 'foo'.

这只是一个C++约定吗?谢谢.

Sto*_*ica 37

问题是C++对象模型,它与Python不同.相比之下,首先让我们回答一下:Python在异常对象中存储什么来打印密钥?它是一个使该对象保持活力的引用.

这不能简单地在C++中完成.

  1. std::out_of_range无法按原样存储指针或引用.异常的处理程序可能在远处的块中.这意味着在输入处理程序之前,键很可能超出范围.如果引用密钥,我们会得到未定义的行为.

  2. std::out_of_range是一个具体的课程.不是像这样的模板std::map.它不能轻易地将密钥复制到自身.有许多不同的Key类型,显然不能解释所有这些类型.即使它可以,如果复制密钥非常昂贵怎么办?甚至是不可复制的?即使在那种情况并非如此的情况下,如果密钥不能转换为字符串或可打印,该怎么办?

以上几点并不意味着它是不可能的.std::map::at可以抛出一个std::out_of_range类型擦除的子类,依此类推.但我希望你看到它有非平凡的开销.C++就是不为不需要或使用的功能付费.让每个人无条件承担这种开销并不符合这种设计.