我已经写了下面的代码......
#include <iostream>
using namespace std;
struct Error {
Error() { cout << "Constructor called\n"; }
Error(const Error&) { cout << "Copy Constructor called\n"; }
};
void test() {
throw Error();
}
int main() {
try {
test();
}
catch (Error e) {
}
}
我在 C++17 及更高版本上获得以下输出...
Constructor called
Copy Constructor called
甚至 C++17 保证的复制省略也说"Copy elision is mandatory in Throwing and catching exceptions by value"
。我得到了"Copy Constructor called"
as 输出。
我是否遗漏了什么?
老实说,这不是强制性的,见下文,并且它按预期工作 - 当
test()
被调用时,编译器会保留一个内存,如果抛出异常,它将在该内存中构造。直到 C++17,它才能创建并将其复制到该保留存储中Error
。test()
Error
您观察到的复制在此处完成:
catch (Error e)
-Error
从保留存储复制到函数本地参数。在 C++17 之前,输出可能是如果您不想复制对象,请修复它:
catch (Error &e)
或catch (const Error &e)
。class.copy.elision#1.4
标准是说
catch (Error e)
可以视为catch (Error &e)
。注意,可以不是必须。