std::function和std::bind的返回值是什么?

3

我正在尝试理解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);
                                                            ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

请问,有人可以解释一下吗?我该如何修复这个错误?


1
一旦您将a绑定到10,剩下的就只有void(float, std::string const&)了。 - Quentin
还要注意,std::bind在C++17中已被弃用,使用lambda更受欢迎。auto fun = [](float a, std::string const& b) { function(10, a, b); }; - Zereges
2
在现代代码中,Lambda 比 std::bind 更可取。 - user4442671
2
@Zereges std::bind 并没有被废弃。std::bind1st 等已经被废弃,但是 std::bind 仍然有一些用途:http://www.sdowney.org/2017/06/why-stdbind-cant-be-formally-deprecated/ - Alan Birtles
@AlanBirtles 你说得对,我不知道为什么会认为它已经被弃用了。 - Zereges
1个回答

8
你已经接近成功,只需要将 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");

2
我建议在那里使用 auto - Zereges
1
@Zereges 这也解决了问题,但也掩盖了首次失败的原因。 - lubgr
我会保留原来的解释,但建议使用auto代替复杂的返回类型。 - Zereges
糟糕,我迟到了5分钟。 - Superlokkus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接