5

I have this code:

#include <iostream>
#include <functional>
#include <vector>

void fun()
{
    std::cout<<"fun";
}

void gun(int)
{
    std::cout<<"gun";
}

int main()
{
    std::vector<std::function<void(int)>> vec;

    vec.push_back(std::bind(fun));
    vec.push_back(gun);

    vec[0](1);
    vec[1](2);
}

Can you please explain how it's possible for std::bind to return std::function<void(int)> when binding void() function?

How it's possible to call void() function by using void(int) functor?

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • 1
    just as a nitpick: please also provide all the necessary `#include` statements in your code sample (vector, iostreams, functional). Makes it a lot more convenient to copy-paste. – TemplateRex Apr 23 '13 at 06:37

2 Answers2

9

The signature passed as the template argument for function only determines how many place holders (_1) will be bound, and as what types.

The invocation of the actual function only uses the number of arguments actually required by the bound function. In effect, the superfluous parameter is ignored.

Another, more enlightening (?) example, looking at this from the other side:

#include <iostream>
#include <functional>

void gun(int i)
{
    std::cout<<"gun("<<i<<")";
}

int main()
{
    using namespace std::placeholders;
    std::bind(gun, _5)("ignore", 3, "and", 4, 43);
}

Prints

gun(43)
sehe
  • 374,641
  • 47
  • 450
  • 633
  • I'm sorry but this doesn't answer my question: how std::bind can make x params function x+k params std::function? It's clear how it can make from x+k params function x params std::function. – Mircea Ispas Apr 23 '13 at 08:20
  • @Felics to be perfectly blunt, the strict answer would be: "that's implementation defined" - the standard doesn't specify how `std::function` is to be implemented, or, for that matter the return type of `std::bind`. So if you really wanted to know **how** it is implemented, go to your implementation. I thought you were asking about it conceptually, and I think I answered that. – sehe Apr 23 '13 at 08:48
  • @Felics see also [this question](http://stackoverflow.com/questions/13251976/why-do-objects-returned-from-bind-ignore-extra-arguments) – TemplateRex Apr 23 '13 at 09:12
0

How it's possible to call void() function by using void(int) functor?

std::bind(fun) does not return a void() function, it returns a call wrapper of unspecified type.

The usual way to invoke that call wrapper would be with zero arguments, but in most implementations of bind() that type can be called with zero or more arguments and the additional arguments will be ignored (i.e. not passed to the target function)

More generally, for a function F taking N arguments, bind(F) returns a call wrapper that can be called with N or more arguments. If you bind arguments or use placeholders then it will alter the minimum number of arguments needed to invoke the call wrapper.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521