http://www.drdobbs.com/cpp/practical-c-error-handling-in-hybrid-env/197003350?pgno=4
この記事では、Herb Sutterが、例外をスローするには、一時として作成されるため、例外のコピーが必要であり、したがってstd::auto_ptr
、コピーのオーバーヘッドを回避するためにを使用することを説明しています。C ++ 11で利用可能になっている移動セマンティクスに照らして、これはまだ必要ですか?
http://www.drdobbs.com/cpp/practical-c-error-handling-in-hybrid-env/197003350?pgno=4
この記事では、Herb Sutterが、例外をスローするには、一時として作成されるため、例外のコピーが必要であり、したがってstd::auto_ptr
、コピーのオーバーヘッドを回避するためにを使用することを説明しています。C ++ 11で利用可能になっている移動セマンティクスに照らして、これはまだ必要ですか?
確認したところ、標準では許可されています
これらの省略は許可されているため、仕様では、最初にコピーのソースを考慮するか、右辺値として移動する必要があります。つまり、可能であれば、それぞれのオブジェクトが移動されるということです。もちろん、コピーと移動の省略は、最初の選択肢として引き続き許可されます。
右辺値初期化子としてのcatch句パラメーターの例外オブジェクト初期化子の考慮はおそらく標準から削除されると通知されました(一般に、省略したときにプログラムの動作が変更されていないことをすべての場合に検出できるわけではないため)コピー/移動)なので、これに依存しないことをお勧めします(上記の2番目の箇条書き)。
まだ信頼できるのは、 (上記の最初の箇条書き)のように、ローカル変数を例外オブジェクトに移動することです。throw x;
現在、例外オブジェクトからの移動は必須ではありません。
これはC++11の欠陥です。CWG1493を参照してください。
しかし、最新のC ++は、より多くの機能を提供します。「移動セマンティクスと例外を使用して安全に移動する」
struct demo
{
demo() = default;
demo(const demo &) { cout << "Copying\n"; }
// Exception safe move constructor
demo(demo &&) noexcept { cout << "Moving\n"; }
private:
std::vector<int> m_v;
};
int main()
{
demo obj1;
if (noexcept(demo(std::declval<demo>()))){ // if moving safe
demo obj2(std::move(obj1)); // then move it
}
else{
demo obj2(obj1); // otherwise copy it
}
demo obj3(std::move_if_noexcept(obj1)); // Alternatively you can do this----------------
return 0;
}
noexcept(T(std::declval<T>()))
かどうかを確認するために使用できます。これは、 (を使用して)の別のインスタンスを移動することによってのインスタンスを作成するかどうかを決定するためのものです。T
noexcept
T
T
std::move
std::move_if_noexcept
を使用noexcept
して右辺値または左辺値にキャストするを使用することもできます。このようなチェックは、std::vector
および他のコンテナで使用されます。std::move_if_noexcept
moveコンストラクターが例外セーフである場合にのみ、重要なデータの所有権を移動するwhichを使用する必要があります。