跳至內容

複製省略

維基百科,自由的百科全書

複製省略或者譯作「省略不必要的複製」(copy elision),是C++語言標準中定義的編譯優化技術。

當一個class類型temporary object英語temporary variable的臨時對象用於初始化同類型的對象[1]時,複製初始化通常優化為直接初始化;但在語義上仍然需要複製構造函數是可訪問的。[2] 例如:

#include <iostream>

struct C {
  explicit C(int) {}
  C(const C&) { std::cout<<"copy constructor"<<std::endl; } // the copy constructor has a visible side effect
};                     // it modifies an object with static storage duration

int main() {
  C c1(42); // direct-initialization, calls C::C(42)
  C c2 = C(42); // copy-initialization elision as direct-initialization, so as to call C::C(42)
  
  return 0;
}

上例,在g++與Visual C++默認都是複製省略。

throw語句拋出一個異常對象,catch語句匹配一個異常對象,默認是要執行複製構造函數的。如下例:

#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.
}          // 由于异常对象保存在线程信息块TIB中,这里的复制构造不可省略. 这使得调用栈上压栈保存的函数都有机会处理这个异常对象

int main() {
  try {
    f();
  }
  catch(C c) {  // copying the exception object into the temporary in the exception declaration.
  }             // 由于这里是传值的catch批配,因此复制初始化不可省略. 通常用于catch块可能会修改异常对象的内容,但又需要把原来的异常对象重新抛出(re-throw)
}

上例默認應該列印輸出兩次"Hello World!"

GCC的編譯選項-fno-elide-constructors關閉複製省略。

參考文獻

  1. ^ ISO/IEC (2003). ISO/IEC 14882:2003(E): Programming Languages - C++ §12.8 Copying class objects [class.copy] para. 15
  2. ^ Sutter, Herb. More Exceptional C++. Addison-Wesley. 2001.