C++1y 没有从 std::bind 到 std::function 的可行转换

2024-01-31

我正在尝试将转发函数存储到std::function。如果我使用std::bind,我收到错误消息,例如no viable conversion from ...。如果我使用 lambda,它编译没问题。

这是示例代码

#include <functional>

template<typename Handler>void func1(int a, Handler&& handler) {}
template<typename Handler>void func2(Handler&& handler)
{
    // this line compile fine
    std::function<void ()> funcA = [handler = std::move(handler)]() { func1(1, std::move(handler)); };
    // this line got compile error
    std::function<void ()> funcB = std::bind(func1<Handler>, 1, std::move(handler));
}

int main()
{
    func2(&main); // this just a sample, I am using functor as argument in real code
}

两者都尝试g++ --std=c++1y(v4.9.0) 和clang++ --std=c++1y(v3.4.1) 产生相同的结果

编辑:clang++ 错误消息

main.cpp:8:28: error: no viable conversion from 'typename _Bind_helper<__is_socketlike<void (*)(int, int (*&&)())>::value, void (*)(int, int
      (*&&)()), int, int (*)()>::type' (aka '_Bind<__func_type (typename decay<int>::type, typename decay<int (*)()>::type)>') to
      'std::function<void ()>'
    std::function<void ()> funcB = std::bind(&func1<Handler>, 1, std::move(handler));
                           ^       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:14:5: note: in instantiation of function template specialization 'func2<int (*)()>' requested here
    func2(&main);
    ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../include/c++/4.9.0/functional:2181:7: note: candidate constructor not viable: no
      known conversion from 'typename _Bind_helper<__is_socketlike<void (*)(int, int (*&&)())>::value, void (*)(int, int (*&&)()), int, int
      (*)()>::type' (aka '_Bind<__func_type (typename decay<int>::type, typename decay<int (*)()>::type)>') to 'nullptr_t' for 1st argument
      function(nullptr_t) noexcept
      ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../include/c++/4.9.0/functional:2192:7: note: candidate constructor not viable: no
      known conversion from 'typename _Bind_helper<__is_socketlike<void (*)(int, int (*&&)())>::value, void (*)(int, int (*&&)()), int, int
      (*)()>::type' (aka '_Bind<__func_type (typename decay<int>::type, typename decay<int (*)()>::type)>') to 'const std::function<void ()> &'
      for 1st argument
      function(const function& __x);
      ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../include/c++/4.9.0/functional:2201:7: note: candidate constructor not viable: no
      known conversion from 'typename _Bind_helper<__is_socketlike<void (*)(int, int (*&&)())>::value, void (*)(int, int (*&&)()), int, int
      (*)()>::type' (aka '_Bind<__func_type (typename decay<int>::type, typename decay<int (*)()>::type)>') to 'std::function<void ()> &&' for
      1st argument
      function(function&& __x) : _Function_base()
      ^
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../include/c++/4.9.0/functional:2226:2: note: candidate template ignored:
      substitution failure [with _Functor = std::_Bind<void (*(int, int (*)()))(int, int (*&&)())>]: no matching function for call to object of
      type 'std::_Bind<void (*(int, int (*)()))(int, int (*&&)())>'
        function(_Functor);
        ^
1 error generated.

介绍

std::绑定会尝试打电话func1<Handler>左值引用,但是你的实例化func1会让它只接受rvalues.


解释

在这里,我们将您的测试用例减少到最低限度以显示正在发生的情况,下面的代码片段格式不正确,随后将解释原因。

#include <functional>

template<class T>
void foobar (T&& val);

int main() {
  std::function<void()> f = std::bind (&foobar<int>, std::move (123));
}

在上面我们将实例化foobar with T = int,这使得参数类型val成为一个右值引用 to int (int&&).

std::move(123) will 移动构造我们的值存储在创建的对象中std::绑定,但标准说,当std::绑定稍后调用存储的函数,所有参数都传递为TiD cv &; IE。作为lvalues.

此行为是由标准强制执行的(n3797 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf),如章节所述[func.bind.bind]p10.


通过将之前的格式错误的代码片段更改为以下内容,不会引发任何错误,因为foobar<int>现在接受一个左值引用;适合绑定到lvalue传递给我们的函数函数对象由返回std::绑定.

  std::function<void()> f = std::bind (&foobar<int&>, std::move (123));

???

#include <functional>
#include <type_traits>
#include <iostream>

int main() {
  auto is_lvalue = [](auto&& x) {
    return std::is_lvalue_reference<decltype(x)> { };
  };

  auto check = std::bind (is_lvalue, std::move (123));
  bool res   = check (); // res = true
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++1y 没有从 std::bind 到 std::function 的可行转换 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • iOS 13 中的 viewDidAppear 问题

    我刚刚开始使用 iOS 13 进行编码 并且遇到了视图控制器功能的问题 在 iOS 13 之前 我有一个使用此函数呈现的视图控制器 func presentDetail viewControllerToPresent UIViewContr
  • 为什么magento不自动加载父类

    我有一个模块 它将使用我的控制器而不是magento的控制器
  • 日期/时间点/间隔的(关系)数据库性能

    我正在使用 Access SQL 做一个项目 并且进展顺利 我学到了很多关于 Access 和 VBA 的知识 这个网站在这个过程中给了我很大的帮助 现在我面临着一个性能问题 由于我在这种 SQL 工作方面经验很少 所以我来这里是为了一些想
  • 奇怪的乘法结果

    在我的代码中 我在 C 代码中进行了乘法运算 所有变量类型均为 double f1 0 f1 rot 0 xu 0 f1 rot 1 yu 0 f1 1 f1 rot 0 xu 1 f1 rot 1 yu 1 f1 2 f1 rot 0 x
  • C# 表单激活和停用事件

    我有两个表单 主表单和子表单 当 mainForm 失去焦点时 我希望 subForm 消失 然后在 mainForm 重新获得焦点时重新出现 我在 mainForm 上使用 Activated 和 Deactivate 事件来跟踪 mai
  • h2内存表,远程连接

    我在创建内存表 使用 H2 数据库以及在创建和运行该表的 JVM 之外访问它时遇到问题 该文档将 url 构造为jdbc h2 tcp
  • 子模块中的 RouteReuseStrategy

    这是我的延迟加载子模块 NgModule imports CommonModule RouterModule forChild acnpRoutes declarations providers provide RouteReuseStra
  • 使用引号作为键的 Bash hashmap

    在 Bash 中 我想取消设置哈希映射的条目 但我失败了 代码如下 declare A arr arr a b 3 echo arr output a b key a b unset arr key error bash unset arr
  • 存储过程中的返回计数

    我编写了一个存储过程来返回计数 但我得到了一个空值 谁能告诉我我的存储过程中的问题出在哪里 set ANSI NULLS ON set QUOTED IDENTIFIER ON go ALTER PROCEDURE dbo Validate
  • 如何在没有安装服务器的情况下设置 MySQL Workbench 的客户端配置?

    假设我在没有服务器的 Windows 7 上安装了 MySQL Workbench 并且正在连接到远程服务器 如何为工作台设置客户端配置 如 my ini 中的 client 部分 或者也许我以错误的方式获取它并且客户端从它连接到的服务器加
  • Java - Spring Ws - 在 XSD 文件中加载相对包含 (Tomcat 8)

    我创建了一个 Spring Web 服务 它使用以下代码从 XSD 文件集合创建动态 WSDL Resource schema new ClassPathResource schema service XCPD SupportMateria
  • Typescript 中的泛型类型返回

    我有一个 Interface find 其中包含方法 cal 类a1和a2实现了该接口 a1 返回数字 a2 返回字符串 我如何定义一个接口来解决我的问题 下面是所提到内容的片段 interface Ifind cal string cla
  • 用于 Docker 的部署 Rails 应用

    阅读了很多资源 但从部署的角度仍然对 Docker 感到困惑 尝试找出 Docker 环境下 Rails 应用程序的最佳实践 特别感兴趣如何解决以下问题 1 从先前部署的容器访问日志 可以停止 销毁该容器 Rsyslog 系统日志 2 回滚
  • 如何在多项选择的表单服务中分配Go_To_Page?

    刚刚开始在 Google Apps 脚本中使用表单服务 需要根据给出的答案引导表单将用户带到特定页面 这是我当前的代码 form addMultipleChoiceItem setTitle What would you like to d
  • JQuery - 获取调用元素 id

    Problem 在自动完成的源函数中 我想获取选择器的 ID 有没有办法可以遍历调用堆栈并得到这个 做JQuery有这个抽象级别吗 Why 我将在页面上有多个自动完成功能 并且每个自动完成功能将在服务器端以不同的方式处理 我必须使用另一个函
  • 仪器中没有出现泄漏,即使我确信它们存在

    我正在检查仪器是否有泄漏 并且我已设置每秒检查一次 但没有出现泄漏 我确信我的应用程序中一定有一些 有什么可以阻止这些出现吗 有没有一种好方法可以创建泄漏 以便我可以测试仪器中是否出现泄漏 Thanks 创建泄漏很容易 id someObj
  • C++17 中的 std::make_shared() 更改

    In cppref http en cppreference com w cpp memory shared ptr make shared 以下情况直到 C 17 才成立 代码如f std shared ptr
  • 有没有类似 CSS 源映射的东西?

    我使用 jQuery 动态地将 CSS 标签添加到页面中 text css appendTo document head 在 Chrome 开发者工具中查看时 所有 CSS 都显示为 localhost 这并不总是有帮助 有没有类似 CSS
  • DataGrid ScrollIntoView - 如何滚动到未显示的第一行?

    我正在尝试向下滚动带有代码的 WPF DataGrid 我用 int itemNum 0 private void Down Click object sender RoutedEventArgs e if itemNum 1 gt dat
  • C++1y 没有从 std::bind 到 std::function 的可行转换

    我正在尝试将转发函数存储到std function 如果我使用std bind 我收到错误消息 例如no viable conversion from 如果我使用 lambda 它编译没问题 这是示例代码 include