Search code examples
c++c++11std-functionstdbind

Why does std::function can implicit convert to a std::function which has more parameter?


I have the following:

void print_str(std::shared_ptr<std::string> str) {
    std::cout << str->c_str() << std::endl;
}

int main() {
    auto str = std::make_shared<std::string>("Hello");
    std::function<void()> f = std::bind(print_str, str);

    f(); // correctly print: Hello

    return 0;
}

I think the type of std::bind(print_str, str) is std::function<void(std::shared_ptr<std::string>)>, but the code above is correctly running. Is there any trick in std::bind?

env: centos, gcc82


Solution

  • What std::bind does is correct. It uses the value you provided (str) for the call to print_str. So you don't need to specify it anymore and will always be replaced by the bound value.

    #include <iostream>
    #include <functional>
    
    int sum(int value1, int value2) {
        return value1 + value2;
    }
    
    int main() {
    
        std::function<int(int, int)> f1 = std::bind(sum, std::placeholders::_1, std::placeholders::_1);
        std::function<int(int)> f2 = std::bind(sum, 10, std::placeholders::_1);
        std::function<int()> f3 = std::bind(sum, 100, 200);
        std::function<int(int)> f4 = std::bind(sum, std::placeholders::_1, 200);
    
        int a = 1;
        int b = 2;
    
        std::cout << "the sum of " << a << " and " << b << " is: " << f1(a, b) << std::endl;
        std::cout << "the sum of " << 10 << " and " << b << " is: " << f2(b) << std::endl;
        std::cout << "the sum of " << 100 << " and " << 200 << " is: " << f3() << std::endl;
        std::cout << "the sum of " << 200 << " and " << b << " is: " << f4(b) << std::endl;
    
        return 0;
    }
    

    output:

    the sum of 1 and 2 is: 2
    the sum of 10 and 2 is: 12
    the sum of 100 and 200 is: 300
    the sum of 200 and 2 is: 202
    

    f1 binds no values but placeholders and returns an int(int, int) like function

    f2 binds one value and one placeholder and returns an int(int) like function

    f3 binds two values and no placeholder and returns an int() like function

    f4 is like f2 except that the place holder is now the first parameter instead of the second one.

    Your code falls into the f3 case.