繁体   English   中英

我可以用自定义删除器简洁地声明 std::unique_ptr 吗?

[英]Can I succintly declare std::unique_ptr with custom deleter?

我正在处理具有关联的new_free_方法的 C 类型。

new_的类型签名可能会有所不同,但free_始终是void free_something(something*);

目前,我正在以这种方式声明我的unique_ptr ,这似乎过于冗长:

std::unique_ptr<qdr_link_t, decltype(&free_qdr_link_t)> link{new_qdr_link_t(), free_qdr_link_t};

不知何故,我可以用更少的仪式来做到这一点吗? 当我的解除分配器是std::free() function,在https://stackoverflow.com/a/43626234/1047788时,我看到了一个巧妙的解决方案。 我试图创建一个可以参数化释放器的版本,但我一无所获。

我能想到的最好的方法是从上面的声明中创建一个宏。

我一直在使用以下内容:

template <auto fptr>
struct Caller {
    template <class... Args>
    auto
    operator()(Args&&... args) noexcept
    {
        return fptr(std::forward<Args...>(args)...);
    }
};

示例用法:

using qdr_freer = Caller<free_qdr_link_t>;

using unique_qdr_ptr = std::unique_ptr<qdr_link_t, qdr_freer>;

[[nodiscard]] unique_qdr_ptr
make_qdr_unique()
{
    return unique_qdr_ptr{new_qdr_link_t()};
}

此实现虽然使用 C++17 功能,但需要进行一些更改才能在 C++11 中工作。


请注意,尽管Caller看起来很适合std::free ,但严格来说它们不兼容,因为std::free是一个标准库 function 未指定为“可寻址”。

让语言做艰苦的工作!

#include <memory>

struct qdr_link_t;
qdr_link_t* new_qdr_link_t();
void free_qdr_link_t(qdr_link_t*);

template <typename T, typename Deleter>
auto make_unique_ptr(T* raw, Deleter deleter)
{
    return std::unique_ptr<T, Deleter>(raw, deleter);
}

//std::unique_ptr<qdr_link_t, decltype(&free_qdr_link_t)> link{new_qdr_link_t(), free_qdr_link_t};
auto link = make_unique_ptr(new_qdr_link_t(), free_qdr_link_t);

添加std::forward来品尝(如果你在乎的话)。


对于 C++11,您需要将尾随返回类型-> std::unique_ptr<T, Deleter>添加到make_unique_ptr ,或者将其放入“正常”返回类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM