I'm trying to wrap the Windows API functions to check errors when I so choose. As I found out in a previous SO question, I could use a template function to call the API function, and then call GetLastError()
to retrieve any error it might have set. I could then pass this error to my Error
class to let me know about it.
Here's the code for the template function:
template<typename TRet, typename... TArgs>
TRet Wrap(TRet(WINAPI *api)(TArgs...), TArgs... args)
{
TRet ret = api(args...);
//check for errors
return ret;
}
Using this I can have code as follows
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
}
This works wonderfully. However, there is one possible problem. Take the function
void WINAPI someFunc();
When subbing this into the template function, it looks as follows:
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
}
To get around this, I tried creating a version of the template where I replaced TRet
with void
. Unfortunately, this actually just causes an ambiguity of which one to use.
That aside, I tried using
if (strcmp (typeid (TRet).name(), "v") != 0) //typeid(void).name() == "v"
{
//do stuff with variable to return
}
else
{
//do stuff without returning anything
}
However, typeid
is a runtime comparison, so the code still doesn't compile due to trying to declare a void variable, even if it never will.
Next, I tried using std::is_same <TRet, void>::value
instead of typeid
, but found out that it was a runtime comparison as well.
At this point, I don't know what to try next. Is there any possibility of getting the compiler to believe that I know what I'm doing will run fine? I don't mind attaching an extra argument to Wrap
, but I couldn't really get anything out of that either.
I use Code::Blocks with GNU G++ 4.6.1, and Windows XP, as well as Windows 7. Thanks for any help, even if it is telling me that I'll have to end up just not using Wrap
for functions that return void.
typeid
solution is also not portable. The standard makes no guarantees about the string returned bytype_info::name()
. – SpringingWrap <DummyType> (someFunc, arg1, arg2...)
. The DummyType can be replaced with anything (except void) for a void return, and can be left out, or replaced with the actual return type for a different return type. If you make it an answer I'll accept it, thanks :) – Ebullient