Windows APIをラッピングしています。エラーチェックを使いやすくして便利です。現在、グローバルエラーオブジェクトがあり、新しいエラーを処理するための関数set
があります。 set
関数は4つの引数をとります:bool Error::set (const int code, const char * file, const char * const function, const int line);
この関数は、ファイル、関数、およびライン引数を使用して、きれいにフォーマットされたメッセージでそれらを表示します。任意のAPI関数をラップする
エラーの設定を簡単にするために、を使用して、そのAPI関数を呼び出した後にAPI関数が設定したエラーにいつでも対応することができます。setError()
残念ながら、これはこのような何かを探すために、コードが発生します。
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
コンストラクタに問題もあります:あなたはメンバー初期化子の構文を使用して、見ることができるように
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
は、私は、実際に自分自身を制限しています。この問題を解決するために
一つの方法は、すべてのAPI関数をラップすることです:エラーメッセージの
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
function
部分はエラーを発信した機能を教えます。もちろん、それはこれを処理する最悪の可能な方法でなければなりません。
解決策は、variadicテンプレートを使用することです。問題は、私は彼らがこれのために働くようにするために何をすべきか分かりません。私は、最終的なコードは次のいずれかのようになります想像:
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
私は可変引数テンプレートを始める上で物事を読んだが、彼らはすべてこのようなものを設定する方法の無知を私に残してきました。誰かが私を正しい方向に向けることができますか?
私はa similar questionで次のが見つかりました:
#include <iostream>
template<void f(void)>
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
回答者は、可変長引数テンプレートが十分にこれが一般的なようにする必要だろうと指摘しました。それは始まりですが、私は迷っていますし、この問題の助けに感謝しています。
はじめに、すべてのAPI関数がGetLastErrorメカニズムを使用しているわけではありません。そして、さらに厄介なことに、これらのAPI関数が失敗を報告したときにGetLastErrorを呼び出すことは有効です。あなたの質問のコードは失敗するように運命づけられています。 –
ほとんどのWin32 API関数は実際にエラーがあった場合にのみ 'LastError'値*を設定します。成功の場合、彼らは 'LastError'値だけを残します。これには例外があります。 Win32 APIのドキュメントでは、各関数が何をしているかについて正確に説明しています。 –
私はそれを認識しています。 'GetLastError'が0(ERROR_SUCCESS)を返した場合、それは無視されます。私は、他のメカニズムも使用しているパーツを知っていますが、私はそれらのサポートをまだ追加していません。私が拡大し続けると、必要なものを追加します。次のAPI関数呼び出しに備えて処理を終えたときに 'SetLastError(0);'を呼び出すことも可能です。 – chris