24

如何绑定到采用默认参数的函数,而不指定默认参数,然后在没有任何参数的情况下调用它?

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();

}
4

4 回答 4

29

基本上,任何时候您编写foo(x)编译器都会将其转换为foo(x, 23);. 它仅在您实际使用函数名称直接调用时才有效。例如,您不能分配&foovoid(*)(int),因为函数的签名是void(int, int)。默认参数在签名中不起作用。而且,如果将其分配给void(*)(int, int)变量,则有关默认参数的信息将丢失:您无法通过该变量利用默认参数。std::bind将 a 存储void(*)(int, int)在其内部的某个地方,因此丢失了默认参数信息。

C++ 中无法从函数外部获取参数的默认值,因此在绑定时您只能手动提供默认值。

于 2012-05-23T11:40:10.643 回答
10

我认为您可以使用 lambda 模拟您想要的行为。

类似这样的东西:

auto g = [] (){ foo( 23 ); };

编辑:刚刚检查过,似乎工作正常:http: //ideone.com/SPSvi

于 2012-05-23T11:44:05.017 回答
2

我有两个解决方案:

1 - 您可以重载 foo() 并让它使用默认值调用原始文件:

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

inline void foo(int a)
{
    foo(a, 23);
}

2 - 您可以使用静态变量作为默认变量,然后在绑定过程中使用它:

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

auto g = std::bind(foo, 23, foo_default_b);
g();
于 2012-05-23T11:51:51.787 回答
-4

这个答案与 R. Martinho Fernandes 的答案不一致。您确实可以使用boost::bind绑定到默认参数,您只需要放入占位符,如下所示:

boost::bind<void (int, int)>(foo, _1, _2)(12);

foo(12, 23)正如预期的那样,这将调用。虽然我没有测试这个特定的代码,但我根据上面链接的答案在我的代码中做了类似的事情,它适用于gcc 4.8.5.

嗯,我刚刚注意到这是在询问std::bind,而不是boost::bind。我不知道有什么不同,如果有的话。

于 2015-12-23T14:00:40.947 回答