c++ - 如何在 C++ 中声明 std::bind 的 std::invoke_result?

标签 c++ c++17

我想用自定义删除器声明 std::unique_ptr,它将一些参数绑定(bind)到特定函数:

using namespace std::placeholders;
using HandleDeleter = std::invoke_result_t<std::bind, _1, SOME_FLAG>; // !!!
using HandlePtr = std::unique_ptr<handle_t, HandleDeleter>;

void handle_destroy(handle_t *, int flags);
handle_t * raw_handle;

auto deleter = std::bind(handle_destroy, _1, SOME_FLAG);
HandlePtr ptr(raw_handle, deleter);

这行不通,因为 std::bind 本身就是一个巨大的模板构造,具有未指定的返回类型。

如何在我的案例中正确声明 HandleDeleter

最佳答案

std::bind 不是一个单独的可调用函数,而是一个函数模板。因此,您必须选择将哪一个传递给 std::invoke_result_t,这真的很麻烦。

幸运的是,还有更好的选择:

  1. 使用decltype:

    using deleter_t = decltype(std::bind(handle_destroy, _1, SOME_FLAG));
    
  2. 为类使用模板参数推导:

    unique_ptr ptr(raw_handle, deleter);
    

无论如何,不​​使用 std::bind() 通常更简单,并且由于对使用的函数和参数进行硬编码而更有效。尽管您当然可以自由地只硬编码部分:

  1. 使用 lambda 代替 std::bind()。在 C++20 中,无状态的 lambda 甚至可以默认构造:

    auto deleter = [](handle_t* p){ handle_destroy(p, SOME_FLAG); };
    
  2. 定义您自己的自定义删除器类,而不是使用 std::bind:

    struct deleter_t {
        constexpr void operator()(handle_t* p) const noexcept {
            handle_destroy(p, SOME_FLAG);
        }
    };
    

关于c++ - 如何在 C++ 中声明 std::bind 的 std::invoke_result?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56683940/

相关文章:

c++ - 为什么在 std::optional 的某些实现中存在虚拟 union 成员?

c++ - 使用透明 std 函数对象时,我们还需要写空尖括号吗?

c++ - 在通用 lambda 中使用 `if constexpr` 访问成员类型需要两个分支的格式都正确 - gcc 与 clang

c++ - 将 QBitArray 转换为 QByteArray

C++一元右折叠与带逗号运算符的一元左折叠

c++ - 使用 std::optional 通过引用将 std::vector<int> 传递给函数

c++ - 在 Windows 上的目录上使用 fopen

c++ - 寻求帮助解决 c++ 八皇后难题代码

c++ - C++/Qt 中的 undefined reference 错误

c++ - 如何在VS2015中使用PostgreSQL插件静态编译Qt 5.8