Note that there are some explanatory texts on larger screens.

plurals
  1. POCheck at Compile-Time if Template Argument is void
    text
    copied!<p>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 <code>GetLastError()</code> to retrieve any error it might have set. I could then pass this error to my <code>Error</code> class to let me know about it.</p> <p>Here's the code for the template function:</p> <pre><code>template&lt;typename TRet, typename... TArgs&gt; TRet Wrap(TRet(WINAPI *api)(TArgs...), TArgs... args) { TRet ret = api(args...); //check for errors return ret; } </code></pre> <p>Using this I can have code as follows</p> <pre><code>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 } </code></pre> <p>This works wonderfully. However, there is one possible problem. Take the function</p> <pre><code>void WINAPI someFunc(); </code></pre> <p>When subbing this into the template function, it looks as follows:</p> <pre><code>void Wrap(void(WINAPI *api)()) { void ret = api(); //&lt;-- ahem! Can't declare a variable of type void... //check for errors return ret; //&lt;-- Can't return a value for void either } </code></pre> <p>To get around this, I tried creating a version of the template where I replaced <code>TRet</code> with <code>void</code>. Unfortunately, this actually just causes an ambiguity of which one to use.</p> <p>That aside, I tried using </p> <pre><code>if (strcmp (typeid (TRet).name(), "v") != 0) //typeid(void).name() == "v" { //do stuff with variable to return } else { //do stuff without returning anything } </code></pre> <p>However, <code>typeid</code> is a runtime comparison, so the code still doesn't compile due to trying to declare a void variable, even if it never will.</p> <p>Next, I tried using <code>std::is_same &lt;TRet, void&gt;::value</code> instead of <code>typeid</code>, but found out that it was a runtime comparison as well. </p> <p>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 <code>Wrap</code>, but I couldn't really get anything out of that either.</p> <p>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 <code>Wrap</code> for functions that return void.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload