c – 如果模板参数为空,请检查编译时间

前端之家收集整理的这篇文章主要介绍了c – 如果模板参数为空,请检查编译时间前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图包装 Windows API函数来检查错误,当我这样选择.正如我在上一个SO问题中发现的,我可以使用模板函数调用API函数,然后调用GetLastError()来检索它可能设置的任何错误.然后,我可以将此错误传递给我的错误类,让我知道.

以下是模板函数代码

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.不幸的是,这实际上只是导致使用哪一个模糊.

除此之外,我尝试使用

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,但我也不能真正得到任何东西.

我使用GNU G 4.6.1,Windows XP以及Windows 7中的Code :: Blocks.感谢任何帮助,即使它告诉我,我将不得不最终不使用Wrap来返回的功能无效.

解决方法

你可以使用一个帮助类来调整专长:
template <typename F>
struct wrapper
{};

template <typename Res,typename... Args>
struct wrapper<Res(Args...)>
{
    static Res wrap(Res (WINAPI *f)(Args...),Args&& args...)
    {
        Res r = f(std::forward<Args>(args)...);
        // Blah blah
        return r;
    }
};

template <typename... Args>
struct wrapper<void(Args...)>
{
    static void wrap(void (WINAPI *f)(Args...),Args&& args...)
    {
        f(std::forward<Args>(args)...);
        // Blah blah
    }
};

现在,你可以写封装:

template <typename Res,typename... Args>
Res Wrap(Res (WINAPI *f)(Args...),Args&& args...)
{
    return wrapper<Res(Args...)>::wrap(f,std::forward<Args>(args)...);
}

请注意,即使Res无效,它也可以工作.你可以返回一个返回void的函数返回void的表达式.

正如在Wrap(someFunc,true)中,即使是返回void的函数也推导出正确的类型.

猜你在找的C&C++相关文章