更新、2015年:
それでも、引数としてstd::runtime_error
aを受け入れます。これは、どこかに格納されていることを示します。したがって、割り当てまたはコピーの構築はどこかで行われている必要があります。そして、のために、それは操作ではありません。std::string
std::string
std::string
noexcept
runtime_error
(およびlogic_error
)は、型の引数を受け入れるためにのみ必要ですstd::string const &
。コピーする必要はありません。
あなた自身の危険でこれらの過負荷を使用してください。LLVMlibc++はストレージを提供しません。
一方、GNU libstdc ++は、メモリ不足を回避するために慎重につま先立ちします。文字列の内容をコピーしますが、新しいではなく、例外ストレージスペースにコピーしますstd::string
。
それでも、std::string&&
オーバーロードを追加し、shipを使用して、rvalueによって渡されfriend
た引数の内部バッファーを採用し、例外ストレージスペースも節約します。std::string
それがあなたの本当の答えです:「もしあったとしても、非常に注意深く」。
std::runtime_error
sを独自の例外クラスのメンバーとして使用し、それぞれ1つの文字列を格納することで、GCCの寛大さを活用できます。ただし、これはClangではまだ役に立ちません。
元の回答、2011年。これはまだ当てはまります。
スタックの巻き戻し中の例外によりterminate
、が呼び出されます。
ただし、スローされるオブジェクトの作成はアンワインドの一部ではなく、throw
式の前のコードと同じように扱われます。
std::runtime_error::runtime_error( std::string const & )
をスローするstd::bad_alloc
と、runtime_error
例外は失われ(存在しなかった)、bad_alloc
代わりにが処理されます。
デモンストレーション: http: //ideone.com/QYPj3
呼び出しサイトからのを格納する独自のクラスについては、std::string
§18.8.1/2に従う必要があります。
クラス例外から派生する各標準ライブラリクラスTには、公的にアクセス可能なコピーコンストラクタと、例外なしで終了しない公的にアクセス可能なコピー割り当て演算子が必要です。
スタックからスレッドの例外ストレージへのコピーは例外の影響を受けやすいため、これが必要です。§15.1/7:
スローされる式の評価が完了した後、例外がキャッチされる前に、例外処理メカニズムが例外を介して終了する関数を呼び出す場合、std :: terminateが呼び出されます(15.5.1)。
したがって、最初のコピーの後shared_ptr< std::string >
にコピーをサニタイズするには、またはそのようなものを使用する必要があります。