Can I bind to a function that takes default arguments and then call it?

Stephan Dollberg picture Stephan Dollberg · May 23, 2012 · Viewed 8.2k times · Source

How can I bind to a function that takes default arguments, without specifying the default arguments and then call it without any arguments?

void foo(int a, int b = 23) {
  std::cout << a << " " << b << std::endl;
}

int main() {
  auto f = std::bind(foo, 23, 34); // works
  f();


  auto g = std::bind(foo, 23); // doesn't work
  g();

  using std::placeholders::_1;
  auto h = std::bind(foo, 23, _1); // doesn't work either 
  h();

}

Answer

R. Martinho Fernandes picture R. Martinho Fernandes · May 23, 2012

Basically, any time you write foo(x) the compiler translates it to foo(x, 23);. It only works if you actually have a directly call with the function name. You can' t, for example, assign &foo to a void(*)(int), because the function's signature is void(int, int). Default parameters play no part in the signature. And if you assign it to a void(*)(int, int) variable, the information about the default parameter is lost: you can't take advantage of the default parameter through that variable. std::bind stores a void(*)(int, int) somewhere in its bowels, and thus loses the default parameter information.

There is no way in C++ to get the default value of a parameter from outside the function, so you're stuck with manually providing the default value when you bind.