异常和复制构造函数:C++

Gau*_*v K 10 c++

参考http://en.wikipedia.org/wiki/Copy_elision

我运行下面的代码:

#include <iostream>

struct C {
  C() {}
  C(const C&) { std::cout << "Hello World!\n"; }
};

void f() {
  C c;
  throw c; // copying the named object c into the exception object.
}          // It is unclear whether this copy may be elided.

int main() {
  try {
    f();
  }
  catch(C c) {  // copying the exception object into the temporary in the exception declaration.
  }             // It is also unclear whether this copy may be elided.
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出:

Gaurav@Gaurav-PC /cygdrive/d/Trial
$ make clean
rm -f Trial.exe Trial.o

Gaurav@Gaurav-PC /cygdrive/d/Trial
$ make
g++ -Wall Trial.cpp -o Trial

Gaurav@Gaurav-PC /cygdrive/d/Trial
$ ./Trial
Hello World!
Hello World!
Run Code Online (Sandbox Code Playgroud)

我知道编译器可能已经使用不必要的复制对代码进行了优化,但这并没有在这里进行.

但我想问的问题two calls to the copy constructor是,如何制作?

catch(C c) - 因为我们传递的是值,所以这里调用了复制构造函数.

但是throw c如何调用复制构造函数?谁能解释一下?

Alo*_*ave 13

throw c;     
Run Code Online (Sandbox Code Playgroud)

创建一个临时对象,它是抛出的临时对象.临时的创建可能是通过复制/移动构造函数.是的,这个复制/移动可以省略.


参考文献:
C++ 11 15.1抛出异常

§3:

throw-expression初始化一个临时对象,称为异常对象,其类型是通过从throw的操作数的静态类型中删除任何顶级cv限定符并调整类型来确定的........ .

§5:

当抛出的对象是类对象时,即使复制/移动操作被省略,也应该可以访问复制/移动构造函数和析构函数(12.8).