我可以绑定到一个接受默认参数然后调用它的函数吗?

时间:2012-05-23 11:28:43

标签: c++ c++11 bind default-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();

}

4 个答案:

答案 0 :(得分:23)

基本上,只要您编写foo(x),编译器就会将其转换为foo(x, 23);。它只适用于您实际使用函数名称直接调用的情况。例如,您无法将&foo分配给void(*)(int),因为该函数的签名为void(int, int)。默认参数不参与签名。如果将其分配给void(*)(int, int)变量,则有关默认参数的信息将丢失:您无法通过该变量利用默认参数。 std::bind在其内容的某处存储void(*)(int, int),因此会丢失默认参数信息。

C ++中无法从函数外部获取参数的默认值,因此在绑定时手动提供默认值时会遇到困难。

答案 1 :(得分:9)

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

有些事情如下:

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

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

答案 2 :(得分: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();

答案 3 :(得分:-2)

This answer不同意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。我不知道有什么不同,如果有的话。