Search code examples
c++std-functionstdbind

std::function and std::bind return value


I'm trying to understand how std::bind and std::function work. I cannot get the following code to compile:

#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;
}

the compiler complains that:

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);
                                                            ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

please, can someone explain? and how do I fix this error?


Solution

  • You are almost there, just change the type of fun to

    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
    

    Note that you change the function signature when fixing the first function argument of type int to the value 10. Hence, it can't be in the type of the std::function instantiation.

    Further note that Scott Meyers suggests in Item 34 of Effective Modern C++ to replace the std::bind usage with a lambda, e.g.

    auto fun = [](float b, std::string const& s){ function(10, b, s); };
    
    // Identical invocation:
    fun(0.2, "world");