我正在处理一个供应商提供的 C 库(我们称之为
foo
),它提供了大量的 API 调用。所有这些函数都采用(预初始化的)句柄(类型为FOOHandle
)并在成功时返回 0,在失败时返回一些其他数字。在后一种情况下,调用者可以调用 foo_get_errmsg()
来获取保存在自己的缓冲区中的错误的文本描述。没什么太不寻常的。
用C++编程,我想将这些错误变成我自己类型的异常。为此,我使用以下构造函数创建了自己的类
FOOException
:
private:
char buf[1024];
int code;
public:
FOOException(FOOHandle h, int32_t _code) noexcept : code(_code)
{
foo_get_errmsg(code, h, buf);
}
到目前为止一切顺利。
为了帮助转换现有代码,我想添加一个通用包装函数,它将调用指定的 API 调用,检查其结果,然后在必要时抛出一个新的异常:
static auto wrapper(const auto &foofunc, auto&&... args) const
{
auto code = foofunc(args);
switch (code) {
case 0:
return 0;
default:
throw new FOOException(handle, code);
}
}
我的问题是获得那个
handle
...虽然参数总是出现在对FOO函数的所有调用中——因此总是在args...
中——但它并不总是第一个:
foo_analyze(a, handle);
...
foo_meow(handle, a, b, c, d);
是否有某种方法可以从
args...
(通过名称或类型)“钓”出句柄供包装器使用,或者我必须在对 wrapper()
的所有调用中复制它 - 一次包装器本身,然后再次包装被包装的函数?
假设
FooHandle
中只有一个 Args
,你可能会这样做
auto& handle = std::get<FooHandle>(std::forward_as_tuple(std::forward<Args>(args)...));