why does std::bind work here?

Feb 25, 2023 at 6:16pm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <functional>
#include <vector>

int main()
{
    using FType = std::function<int()>;
    std::vector<FType> funcs;
    
    auto bnd = std::bind( [](int x) {return x*2;} , 3);
    funcs.push_back(bnd);
    
    std::cout << funcs[0]();
    
    
}


The function passed to std::bind has an argument but FType has no parameters.

Thanks
Feb 25, 2023 at 7:19pm
I could be wrong, but I'd say it's because of the wonders of auto typing on line 10.
Feb 25, 2023 at 7:24pm
ok but why does line 11 work? bnd is a different type to the element of the vector (FType only has no parameters)
Feb 25, 2023 at 7:59pm
Are you on C17 or later?

From https://en.cppreference.com/w/cpp/utility/functional/bind

Member type result_type
1) (deprecated in C++17) If F is a pointer to function or a pointer to member function, result_type is the return type of F. If F is a class type with nested typedef result_type, then result_type is F::result_type. Otherwise no result_type is defined.
2) (deprecated in C++17) result_type is exactly R.


With C20, the return type of F is unspecified.
I have no clue what auto does with an unspecified return type.
Last edited on Feb 25, 2023 at 8:00pm
Feb 25, 2023 at 8:12pm
The result of the call to bind is a function object that's roughly equivalent to this lambda expression:
[]{ return [](int x) { return x*2; }(3) };
It has no parameters.

This reflects the purpose of bind, which is to to associate ("bind") a concrete value to a parameter ("free variable"). The terminology comes from lambda calculus.

With C20, the return type of F is unspecified.

It means that C++ standard doesn't say what type should be returned from std::bind. It still has a normal return type, but it's chosen by the implementation at its discretion.


Last edited on Feb 25, 2023 at 11:07pm
Feb 25, 2023 at 10:30pm
It means that C++ standard doesn't say what type should be returned from std::bind. It still has a normal return type, but it's chosen by the implementation at its discretion.

Looking at what the return type is when compiling with MSVC the lambda has a return type of int, if I'm reading the expansion correctly. The entire expanded return type uses a couple of MSVC implementation helpers, std::_Binder and std::_Unforced, along with the lambda.

std::_Binder<std::_Unforced, lambda [](int x)->int, int> bnd

Whatever is going on MSVC appears to accept the code as valid and compiles/runs without an error or warning.
Topic archived. No new replies allowed.