Я пытаюсь обернуть функции 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 <TRet, void>::value
вместо typeid
, но обнаружил, что это также сравнение во время выполнения.
На данный момент, я не знаю, что попробовать дальше.Есть ли возможность заставить компилятор поверить, что я знаю, что я делаю, будет работать нормально?Я не против присоединения дополнительного аргумента к Wrap
, но я не могу ничего из этого извлечь.
Я использую Code :: Blocks с GNU G ++ 4.6.1 и Windows XP,а также Windows 7. Спасибо за любую помощь, даже если она говорит мне, что мне придется в итоге просто не использовать Wrap
для функций, которые возвращают void.