有问题的代码是这样的:

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.1clang 6.0编译代码,使用-O3选项,输出为
First throw
A copy has occoured!
Caught exception
Second throw
Caught exception
第一个throw与您的示例相对应。即使可以省略e的副本,但gccclang都不会实现复制省略。
第二个throw具有一个匿名临时文件,并且没有副本发生。

关于c++ - 抛出临时变量而不是局部变量-为什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53412425/

10-12 07:36
查看更多