我想打开一个文件并对文件执行一些操作,testOpen 和 testClose 是 API 函数 test_open 和 test_close 的包装器,因此如果在执行这些操作时出现错误,我可以抛出一个异常,这将有助于追踪错误。
为了实现这一点,我使用了一个带有自定义删除器的
std::unique_ptr
,该删除器对文件执行关闭操作。现在,由于我没有直接使用 API 函数,而是使用 API 调用的包装器,我想将函数参数 std::string const& path
作为参数传递给包装器 testClose(test*, std::string&)
但是我无法将
std::string const& path
传递给 unique_ptr 的自定义删除器参数的 lambda 函数。
test 是一个 C 库。
这是我试过的。
using test_ptr = std::unique_ptr<test, void(*)(test*)>;
test_ptr testOpen(std::string const& path) {
test_ptr tester(test_open(...), [path](test* t){
testClose(t, path); // a wrapper around the test_close API function which closes the file at path and might throw an exception if the close operation fails.
});
if(!tester) {
throwTestError(path); // throws an exception
}
return test;
}
但是抛出一个
error: no matching function for call to 'std::unique_ptr<test, void(\*)(test*)>::unique_ptr(test*, testOpen(std::string const&)::<lambda(test*)>)'
这似乎也很好用。
using test_ptr = std::unique_ptr<test, void(*)(test*)>;
test_ptr testOpen(std::string const& path) {
test_ptr tester(test_open(...), [](test* t){
test_close(t);
});
if(!tester) {
throwTestError(path); // throws an exception
}
return test;
}
当我不使用 Wrapper
testClose()
而是直接调用 API 时。
有没有一种方法可以使用我的包装器
testClose()
而不是进行 API 调用?
带捕获的 lambda 永远 不能用作函数指针。只有无捕获的 lambda 可以用于函数指针。
如果你有一个最新的编译器并且可以使用 C++20 标准构建,你可以为
test_ptr
类型使用模板类型别名,并为函数使用 auto
返回类型推导:
template<typename F>
using test_ptr = std::unique_ptr<test, F>;
auto testOpen(std::string const& path) {
test_ptr tester(test_open(), [path](test* t){
testClose(t, path); // a wrapper around the test_close API function which closes the file at path and might throw an exception if the close operation fails.
});
if(!tester) {
throwTestError(path); // throws an exception
}
return tester;
}
虽然这个 会构建,但您需要在使用指针的任何地方使用
auto
和类型推导。类型别名模板 test_ptr
不可能用于 testOpen
返回的对象。这是一个主要的限制因素,可能会阻止它用于您的用例。