微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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的函数也推导出正确的类型.

原文地址:https://www.jb51.cc/c/113689.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐