1

私のコードがこの構造を何度も繰り返していることに気付きました:

if( someErrorHappened ){
        string errorMsg = "Falcon Punch!";
        ::GetErrorLoggerInstance()->Log( LOG_TYPE_ERROR, "class", "method", errorMsg );
        throw SomeCustomException( errorMsg );
}

テンプレート関数を記述して、これらすべてを次のようなワンライナーに置き換えることができると考えました。

LogAndThrowIfError<SomeCustomException>( someErrorHappened, "class", "method", "Falcon Punch!" );

基本的なテンプレートの知識があれば、問題なく実行できます。私の質問は、テンプレート引数が特定のクラスから継承されていないクラスである場合、Boost を使用してコンパイル エラーが発生するようにすることはできますか? (つまり、この関数をカスタム例外にのみ使用したい)。C# のwhereジェネリックのキーワードのようなものです。

これは大げさに思えるかもしれませんが、アプリケーションにはマネージド コードとアンマネージド コードがあり、カスタム ネイティブ例外はカスタム マネージド例外にマップされているため、これを強制する必要があります。そのため、これは例外でのみ使用する必要があります。

私は Visual Studio 2010 で作業しているので、派手な C++11 のすべてを持っているわけではありません。

4

2 に答える 2

3

試してみてください

 BOOST_STATIC_ASSERT(( boost::type_traits::is_base_of< ExceptionBaseClass, T >::value ));

@Zolyomiが回答に投稿したのと同じチェックを内部的に行います。

于 2012-05-18T17:31:57.590 に答える
2

実際には、これを行うために Boost や特別なライブラリは必要ありませんが、必要に応じてそれらを使用できます。最も簡単な方法は、次のようなことをすることです

template<typename T>
void LogAndThrowIfError(...options...)
{
    static ExceptionBaseClass *CheckBaseClass_WriteYourErrorMessageHere = static_cast<T*>(null);
    ... your logging code here ...
}

テンプレートが新しい型 T でインスタンス化されるたびに、T* が ExceptionBaseClass* に変換可能であることを 1 回チェックします。これは基本的に、T が ExceptionBaseClass から派生したものと同等です。

チェックが失敗した場合、エラー メッセージはそれほど単純ではない可能性があることに注意してください。Boost または他のライブラリに依存することを気にしない場合は、より適切なエラー メッセージが表示される場合があります。

于 2012-05-18T13:52:29.167 に答える