私が選択したときにエラーをチェックするためにWindows API関数をラップしようとしています。以前のSOの質問で分かったように、テンプレート関数を使用してAPI関数を呼び出し、GetLastError()
を呼び出して設定したエラーを取得することができます。私はこのエラーを私のError
クラスに渡して、私に知らせてもらうことができました。これは素晴らしい作品テンプレート引数がvoidの場合はコンパイル時にチェック
int WINAPI someFunc (int param1, BOOL param2); //body not accessible
int main()
{
int ret = someFunc (5, true); //works normally
int ret2 = Wrap (someFunc, 5, true); //same as above, but I'll get a message if there's an error
}
を次のように、この私は、コードを持って使用することで、
template<typename TRet, typename... TArgs>
TRet Wrap(TRet(WINAPI *api)(TArgs...), TArgs... args)
{
TRet ret = api(args...);
//check for errors
return ret;
}
:
はここでテンプレート関数のコードです。しかし、1つの可能性のある問題があります。テンプレート関数にこれを下塗りすると、次のように見え、機能
void WINAPI someFunc();
してください:
void Wrap(void(WINAPI *api)())
{
void ret = api(); //<-- ahem! Can't declare a variable of type void...
//check for errors
return ret; //<-- Can't return a value for void either
}
これを回避するために、私は私がvoid
でTRet
を置き換えテンプレートのバージョンを作成してみました。残念なことに、これは実際にどちらを使用するかのあいまいさを引き起こします。さておき、私は
if (strcmp (typeid (TRet).name(), "v") != 0) //typeid(void).name() == "v"
{
//do stuff with variable to return
}
else
{
//do stuff without returning anything
}
を使用してみましたが、typeid
は、実行時の比較なので、コードはまだ原因も、それは決してならば、ボイド変数を宣言しようとしているにコンパイルされません
。
次に、typeid
の代わりにstd::is_same <TRet, void>::value
を使用してみましたが、実行時の比較でもあることが判明しました。
この時点で、私は次に何を試すべきか分かりません。コンパイラが私がやっていることがうまく動作すると知っていると信じる可能性はありますか?私はWrap
に余分な議論を付けても構いませんが、実際には何も得られませんでした。
私はCode :: BlocksをGNU G ++ 4.6.1、Windows XP、Windows 7と一緒に使用しています。助けてくれてありがとうございます。Wrap
を使用しないで終わらなければならないと言っていますvoidを返す関数の場合
私は戻り値の型をvoidに特化した理由を理解しています(戻り値の型を明確にすることはできません)。void **と**特殊なパラメータを追加すると何が起こるのでしょうか?明示的な型で呼び出す必要があるかもしれません。 – Tod
興味深い質問です。サイドノート:静的にチェックされないことに加えて、 'typeid'ソリューションは移植性がありません。標準では 'type_info :: name()'によって返される文字列について保証していません。 – Thomas
私は2つを組み合わせることを考えなかった。やってみます。 typeidの問題についてのヘッドアップにも感謝します。 – chris