有问题的代码是这样的:
struct something_bad_happened_exception : std::exception {};
void foo() {
something_bad_happened_exception e;
throw e;
}
clang发出警告,内容为:
这意味着
foo()
应该更改为:void foo() {
throw something_bad_happened_exception();
}
为什么最好抛出一个临时变量而不是一个局部变量?
最佳答案
根据throw expression上的cpp引用:
这样,您的代码就可以了,但是会调用一个拷贝构造函数,这在效率方面可能是不可取的。不过,如果(强调我的话),可能会出现copy elision
作为示例,请考虑以下代码
#include <exception>
#include <iostream>
struct something_bad_happened_exception : std::exception {
something_bad_happened_exception(const something_bad_happened_exception& r) {
std::cout << "A copy has occoured!" << std::endl;
}
something_bad_happened_exception() { }
};
int main()
{
std::cout << "First throw" << std::endl;
try {
const something_bad_happened_exception e;
throw e;
}
catch (const std::exception& ex)
{
std::cout << "Caught exception" << std::endl;
}
std::cout << "Second throw" << std::endl;
try {
throw something_bad_happened_exception();
}
catch (const std::exception& ex)
{
std::cout << "Caught exception" << std::endl;
}
return 0;
}
使用gcc 8.2.1
和clang 6.0
编译代码,使用-O3
选项,输出为First throw
A copy has occoured!
Caught exception
Second throw
Caught exception
第一个throw
与您的示例相对应。即使可以省略e
的副本,但gcc
和clang
都不会实现复制省略。第二个
throw
具有一个匿名临时文件,并且没有副本发生。关于c++ - 抛出临时变量而不是局部变量-为什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53412425/