4

コード レビューの後、try/catch ブロックのコピー エリソンに問題がありました。このページを読んだ後: cppリファレンスガイド、特にこの段落:

例外を処理するとき、catch 句の引数がスローされた例外オブジェクトと同じ型 (最上位の cv 修飾を無視) である場合、コピーは省略され、catch 句の本体は例外オブジェクトに直接アクセスします。参照によってキャッチされた場合

私は、キャッチ内の引数のコピー省略が自動的に実行されると考えていましたが、レビュー担当者の 1 人が、コンパイラによってコピー省略が実行されなかったことを示す簡単なテストを実行しました。

#include <iostream>

class A
{
public:
   A(){}
   A(const A&){
    std::cout<<"COPY CONSTRUCTOR\n";
   }
};

int main()
{
    try {
       throw A{};
    } catch(A a) {
       throw a;
    }
    return 0;
 }

でコンパイルする場合:

g++ a.cpp -std=c++11 -O3

次の出力を得ました

COPY CONSTRUCTOR
COPY CONSTRUCTOR
terminate called after throwing an instance of 'A'
Aborted (core dumped)

(例外がスローされたときにコピーコンストラクターを1回だけ呼び出す)のような出力を期待していました:

COPY CONSTRUCTOR
terminate called after throwing an instance of 'A'
Aborted (core dumped)

テストは、g++ バージョンの Linux Ubuntu 16.04 で実行されました。

 g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

テストケースは無効ですか、それともコピー省略に関する私の理解は間違っていますか? ご助力ありがとうございます

4

1 に答える 1