gpt4 book ai didi

c++ - 在 Visual Studio 与 g++ 中将 std::out_of_range 切片为 std::exception

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:31 24 4
gpt4 key购买 nike

我偶然注意到了以下行为(通过引用错过了捕捉),但我找不到信息,如果我事先知道它,我就可以预测它。

用最小的例子

#include <iostream>
#include <stdexcept>


int main()
{
try
{
// Added this and the next line to check that the exception
// created has already the what() set to the input string.
std::out_of_range d("Out of range exception");
std::cout << "d.what() = " << d.what() << std::endl;
throw d;
}
catch (std::exception e) // Captured by value
{
std::cout << e.what() << std::endl;
}

}

如果我用 g++ -std=c++17 和 Visual C++ 编译它,我会得到不同的行为。第一个打印 d.what() = Out of range exception\nstd::exception,而第二个打印 d.what() = Out of range exception\nOut of range异常

原则上,当 std::out_of_range 被值捕获并转换为 std::exception 类型时,可以进行切片。这意味着在打印 what() 时,我可能不会得到与 std::out_of_range 对象中的对象相同的行为。

问题:我不知道如何解释的部分是两个编译器的不同行为。这是因为这种切片在 C++ 标准化中是未定义的行为,还是这两个编译器之一不符合它?

额外观察:我刚刚注意到 this link没有提到 std::exception 类具有输入 const char* const & 的构造函数,而在 the Microsoft website 中他们包括它。我偶然的例子表明,他们确实以不同的方式实现了这些类。我的问题仍然是它们是否被允许(如果此行为未定义)或者它们中的一个是否不遵守以及是哪个。

最佳答案

对象还在被切片;您可以使用 typeid( e ).name() 打印出实际类型,它显示为 std::exception。如您所见,MSVC 实现 what() 以返回指向在 std::exception 构造时设置的字符串的指针,因此当 out_of_range 异常被切回基本异常。

根据 https://en.cppreference.com/w/cpp/error/exception/exception , what() “返回一个实现定义的字符串”,所以 MSVC 可以自由地这样做。

要打印类型,请将其添加到您的 catch block 中:

std::cout << "e.what() = " << e.what() << " Actual type = " << typeid( e ).name() << std::endl;

关于c++ - 在 Visual Studio 与 g++ 中将 std::out_of_range 切片为 std::exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55067913/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com