【发布时间】:2020-01-02 16:28:21
【问题描述】:
我正在玩回调函数,并希望通过std::bind 注册多个签名不同的函数(尽管它们都返回void)。将std::bind 的结果分配给std::variant 会导致“转换为非标量类型”错误。是歧义错误吗?我可以向编译器提供更多信息吗?
删除std::bind(允许分配)不是一个选项,因为我希望使用一些注册回调
template <typename Function, typename... Args>
void register(Function &&f, Args &&... args)
{
variant_of_multiple_func_types = std::bind(f, args...);
}
例如:
std::variant<std::function<void()>, int> v = std::bind([]() noexcept {});
有效,但是
std::variant<std::function<void()>, std::function<void(int)>> v = std::bind([]() noexcept {});
没有,虽然我希望它编译成包含 std::function<void()> 的 std::variant。
我在 GCC 7.4.0 中使用-std=c++17 收到以下编译错误:
error: conversion from ‘std::_Bind_helper<false, main(int, char**)::<lambda()> >::type {aka std::_Bind<main(int, char**)::<lambda()>()>}’ to non-scalar type ‘std::variant<std::function<void()>, std::function<void(int)> >’ requested
std::variant<std::function<void()>, std::function<void(int)>> v = std::bind([]() noexcept {});
【问题讨论】:
-
半相关说明:为什么必须为工作示例中的 lambda 指定
noexcept才能通过编译? -
您能否通过“为什么必须为工作示例中的 lambda 指定
noexcept”来解释您的意思?省略noexcept仍然适用于我使用相同的编译器和标志。 -
你为什么使用
std::bind和 lambda?std::bind在无法使用 lambda 时很有用。在您的代码中,std::bind已经过时了。 -
std::bind([]() noexcept {})("lot", "of", "unused", "parameter")有效。您可以将任意数量的参数传递给绑定对象,place_holder(std::bind([](int) {/*..*/}, place_holder::_5)) 最需要它。 -
@Jonas,哎呀,我错过了我启用了大多数警告。编译失败,因为指定了
-Werror=noexcept。
标签: c++ c++17 std-function std-variant