如何将变量传递给 std::unique_ptr 的自定义删除器(lambda 函数)?

问题描述 投票:0回答:1

我想打开一个文件并对文件执行一些操作,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 c++17 smart-pointers unique-ptr
1个回答
0
投票

带捕获的 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
返回的对象。这是一个主要的限制因素,可能会阻止它用于您的用例。

© www.soinside.com 2019 - 2024. All rights reserved.