11

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.
}

私が得た出力:

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!

コンパイラが不要なコピーを使用してコードを最適化した可能性があることは理解していますが、ここでは行っていません。

しかし、私が聞きたいのは、どのようtwo calls to the copy constructorに作られているのですか?

catch(C c)- 値渡しなので、ここでコピー コンストラクターが呼び出されます。

しかし、throw cコピー コンストラクターはどのように呼び出されるのでしょうか。誰か説明できますか?

4

3 に答える 3

14
throw c;     

一時オブジェクトを作成し、スローされるのはこの一時オブジェクトです。一時的な作成は、コピー/移動コンストラクターを介して行われる場合があります。はい、このコピー/移動は省略できます。


参照:
C++11 15.1 例外のスロー

§3:

throw 式は、例外オブジェクトと呼ばれる一時オブジェクトを初期化します。その型は、throw のオペランドの静的型から最上位の cv 修飾子を削除し、型を調整することによって決定されます........ .

§5:

スローされたオブジェクトがクラス オブジェクトの場合、コピー/移動操作が省略されていても (12.8)、コピー/移動コンストラクターとデストラクタにアクセスできる必要があります。

于 2013-05-08T05:03:14.877 に答える