2016-05-10 1 views
0

私はそうのように、文字列(std::stringまたはconst char*のいずれかを)投げ経由してエラーを処理するC++でプログラムを書いています:スローされた式をあるキャッチブロックから別のキャッチブロックに転送する方法は?

if (/* failure condition 1 */) 
    throw std::string("Error 1 : ...") + std::to_string(foo); 

if (/* failure condition 2 */) 
    throw "Error 2 : ..."; 

その後、私は彼らにこの方法をキャッチします:

try { 
    thisIsLikelyToThrowErrors(); 
} catch (const std::string& e) { 
    std::cerr << ":(" << e << std::endl; 
} catch (const char* e) { 
    std::cerr << ":(" << e << std::endl; 
} 

私は希望最初のcatchブロックから2番目のブロックに文字列を転送することにより、同じ行を2回書くのを避けるには、

try { 
    thisIsLikelyToThrowErrors(); 
} catch (const std::string& e) { 
    throw e.c_str(); // Does not work 
} catch (const char* e) { 
    std::cerr << ":(" << e << std::endl; 
} 

しかし、このコードは機能しません。スローされたchar const*は単に捕まえられません。

これを行う方法はありますか?

感謝:)

答えて

2

由来します。、あなたが行うことができますあなたの例では

inline void HandleStringyException(const char* excStr) 
{ 
    //do something 
} 

その後:

try { 
    thisIsLikelyToThrowErrors(); 
} catch (const std::string& e) { 
    HandleStringyException(e.c_str()); 
} catch (const char* e) { 
    HandleStringyException(e); 
} 

P.S.例外はポリモーフィックに処理するほうがよいことを言及する必要があります。そのためには、をスローしたオブジェクトを賢明に選択する必要があります。他の人に言及されているように、文字列やポインタのようなオブジェクトを投げるのは悪い習慣であり、一般的にstd :: exceptionから派生したオブジェクトを投げたいとします。しかし、時には、投げたコードがあなたのコントロール下にないので、あなたはそれを最大限活用しなければなりません。それは別の議論だと思う。

3

いいえ、あなたはこれを行うことはできません。

[C++14: 15.1/1]:例外がスローされた場合、制御は、整合型(15.3)と最も近いハンドラに転送されます。 「nearest」は、tryキーワードに続く複合ステートメントまたはctor-initializerが、最新のスレッドによって入力され、まだ終了していないのハンドラを意味します。

try { 
    try { 
     thisIsLikelyToThrowErrors(); 
    } 
    catch (const std::string& e) { 
     throw e.c_str(); // Does not work 
    } 
} 
catch (const char* e) { 
    std::cerr << ":(" << e << std::endl; 
} 

うわ:

あなたが全体の巣にtry/catchペアを持っているでしょう!

しかし、今、あなたは(あなたがそれ-投げ再あれば、それは生きていたい)あなたはそのC-文字列バッファを投げてきたという点で、std::stringeダイスた後、別の問題を抱えています。おそらくこれを一般的に回避しようとしますか?

代わりに実際の例外をスローします。

投げるだけstd::stringかだけconst char*

+0

"例外の最後に残っているアクティブなハンドラが再スローされた以外の方法で終了すると、オブジェクトが破棄されます。" < - 外部ハンドラが 'const char *'をキャッチする前に文字列が削除されます。 – Barry

+0

@バリー:合意。 –

1

あなたの実際の問題に簡単な解決策があります。

あるいはさらに良い投球何かがあなたのキャッチ句からそれを呼び出して、外部の独立した機能で、共通のセットアップを扱うことができるstd::exception

+0

これは「はい」ではありません。それは「試してもいない」。合理的な提案(私はそれを自分で作った)が、あなたは実際にその質問に答えなかった。 –

+0

@LightnessRacesinOrbitあなたは正しいです。私はXYパスを行った。 – bolov

関連する問題