Я пытаюсь обернуть функции Windows API для проверки ошибок, когда захочу. Как я выяснил в предыдущем вопросе SO, я мог бы использовать функцию шаблона для вызова функции API, а затем вызвать GetLastError()
, чтобы получить любую ошибку, которую она могла установить. Затем я мог бы передать эту ошибку моему классу Error
, чтобы сообщить мне об этом.
Вот код шаблонной функции:
template<typename TRet, typename... TArgs>
TRet Wrap(TRet(WINAPI *api)(TArgs...), TArgs... args)
{
TRet ret = api(args...);
//check for errors
return ret;
}
Используя это, я могу получить следующий код
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
}
Это прекрасно работает. Однако есть одна возможная проблема. Возьмем функцию
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
}
Чтобы обойти это, я попытался создать версию шаблона, в которой я заменил TRet
на void
. К сожалению, это на самом деле просто вызывает двусмысленность того, какой из них использовать.
Помимо этого, я попытался использовать
if (strcmp (typeid (TRet).name(), "v") != 0) //typeid(void).name() == "v"
{
//do stuff with variable to return
}
else
{
//do stuff without returning anything
}
Однако typeid
является сравнением во время выполнения, поэтому код по-прежнему не компилируется из-за попытки объявить переменную void, даже если этого никогда не произойдет.
Затем я попытался использовать std::is_same
вместо typeid
, но обнаружил, что это также сравнение во время выполнения.
На данный момент я не знаю, что делать дальше.Есть ли возможность заставить компилятор поверить, что я знаю, что то, что я делаю, будет работать нормально? Я не возражаю против присоединения дополнительного аргумента к Wrap
, но и из этого я ничего не смог получить.
Я использую Code::Blocks с GNU G++ 4.6.1 и Windows XP, а также Windows 7. Спасибо за любую помощь, даже если мне говорят, что в конечном итоге мне придется просто не использовать Wrap
для функций, возвращающих void.