gpt4 book ai didi

c++ - 如果模板参数无效,请在编译时检查

转载 作者:IT老高 更新时间:2023-10-28 23:18:29 33 4
gpt4 key购买 nike

我正在尝试包装 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();

将 this 放入模板函数时,如下所示:

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 附加一个额外的参数,但我也无法从中得到任何东西。

我在 GNU G++ 4.6.1、Windows XP 和 Windows 7 中使用 Code::Blocks。感谢您的帮助,即使它告诉我最终只能不使用 Wrap返回 void 的函数。

最佳答案

您可以使用帮助类来微调特化:

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)...);
}

请注意,即使 Resvoid,它也能正常工作。您可以在返回 void 的函数中return返回 void 的表达式。

推导出正确的类型,如 Wrap(someFunc, 5, true),即使对于返回 void 的函数也是如此。

关于c++ - 如果模板参数无效,请在编译时检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9625526/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com