why does std::bind work here?


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
I could be wrong, but I'd say it's because of the wonders of auto typing on line 10.
ok but why does line 11 work? bnd is a different type to the element of the vector (FType only has no parameters)
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
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
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.