私は Windows API をラップしており、エラー チェックを使いやすく便利なものにしたいと考えています。set
現在、新しいエラーを処理する関数を備えたグローバル エラー オブジェクトがあります。このset
関数は 4 つの引数を取ります。bool Error::set (const int code, const char * file, const char * const function, const int line);
この関数は、ファイル、関数、および行の引数を使用して、適切にフォーマットされたメッセージで表示します。
エラーの設定を簡単にするために、マクロがあります。#define setError() error.set (GetLastError(), __FILE__, __FUNCTION__, __LINE__);
これsetError()
により、API 関数を呼び出した後に追加することで、いつでも API 関数が設定したエラーに応答することができます。
残念ながら、これによりコードは次のようになります。
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
コンストラクターにも問題があります。
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
ご覧のとおり、メンバー初期化構文を使用することで、実際に自分自身を制限しています。
これを修正する 1 つの方法は、すべての API 関数をラップすることです。
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
エラー メッセージのfunction
一部で、エラーの原因となった関数がわかります。もちろん、それはこれに対処するための最悪の方法でなければなりません。
解決策は、可変個引数テンプレートを使用することです。問題は、彼らをこのために働かせるために私が何をすべきかわからないということです. 最終的なコードは次のいずれかのようになると思います。
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
可変引数テンプレートの開始に関する記事を読んだことがありますが、このようなものを設定する方法がわかりません。誰かが私を正しい方向に向けることができますか?
同様の質問で次のことがわかりました。
#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;
}
回答者は、これを十分に汎用的にするには可変個引数テンプレートが必要であると指摘しました。それは始まりですが、私は迷子になり、この問題に関する助けに感謝しています.