【问题标题】:std::function and std::bind return valuestd::function 和 std::bind 返回值
【发布时间】:2019-03-12 14:56:47
【问题描述】:

我试图了解 std::bind 和 std::function 是如何工作的。 我无法编译以下代码:

#include <iostream>
#include <string>
#include <functional>

void function(int a, float b, std::string const &s)
{
    std::cout << "printing function" << std::endl;
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << s << std::endl;
}

int main(int argc, char *argv[])
{
    std::bind(&function, 10, 11.1, "hello")();
    std::function<void(int, float, std::string const&)> fun = std::bind(&function, 10, std::placeholders::_1, std::placeholders::_2);

    fun(0.2, "world");

    return 0;
}

编译器抱怨:

main.cpp: In function 'int main(int, char**)':
main.cpp:16:69: error: conversion from 'std::_Bind_helper<false, void (*)(int, float, const std::__cxx11::basic_string<char>&), int, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type {aka std::_Bind<void (*(int, std::_Placeholder<1>, std::_Placeholder<2>))(int, float, const std::__cxx11::basic_string<char>&)>}' to non-scalar type 'std::function<void(int, float, const std::__cxx11::basic_string<char>&)>' requested
  std::function<void(int, float, std::string const&)> fun = std::bind(&function, 10, std::placeholders::_1, std::placeholders::_2);
                                                            ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

请问,有人可以解释一下吗?以及如何解决此错误?

【问题讨论】:

  • a 绑定到10 后,剩下的只是void(float, std::string const&amp;)
  • 另请注意,std::bind 在 C++17 中已被弃用,而使用 lambda 更为可取。 auto fun = [](float a, std::string const&amp; b) { function(10, a, b); };
  • 值得指出的是,在现代代码中,lambdas 现在总是比 std::bind 更可取。
  • @Zereges std::bind 绝不会被弃用。 std::bind1st 等已弃用,但 std::bind 仍有一些用途:sdowney.org/2017/06/why-stdbind-cant-be-formally-deprecated
  • @AlanBirtles 你说得对,我不知道为什么我认为它已被弃用

标签: c++ std-function stdbind


【解决方案1】:

你快到了,把fun的类型改成

std::function<void(float, std::string const&)> fun = std::bind(...);
//                ^^ no more int here

fun(0.2, "world");
//  ^^^^^^^^^^^^ those types must match the above signature

请注意,将int 类型的第一个函数参数固定为值10 时,您会更改函数签名。因此,它不能是std::function 实例化的类型。

进一步注意,Scott Meyers 在 Effective Modern C++ 的第 34 条中建议用 lambda 替换 std::bind 用法,例如

auto fun = [](float b, std::string const& s){ function(10, b, s); };

// Identical invocation:
fun(0.2, "world");

【讨论】:

  • 我建议在那里使用auto
  • @Zereges 这也解决了这个问题,但也首先掩盖了失败的原因。
  • 我将保留原样解释,但也建议使用auto 而不是复杂的返回类型。
  • 我迟到了 5 分钟。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多