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

时间:2021-04-03 23:19:14

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

}

4 个解决方案

#1


21  

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.

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

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.

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

#2


8  

I think you could simulate the behaviour you want using a lambda.

我想你可以使用lambda来模拟你想要的行为。

Something along the lines of this:

有点像这样:

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

EDIT: Just checked, and seems to work fine: http://ideone.com/SPSvi

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

#3


0  

I have two solutions:

我有两个解决方案:

1 - You can overload foo() and have it call the original with defaults:

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

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

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

2 - You can use a static variable as default and then use it in the binding process:

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

#4


-1  

This answer disagrees with R. Martinho Fernandes' answer. You can indeed use boost::bind to bind to the default parameters, you just need to put placeholders in, as so:

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

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

This will call foo(12, 23), as expected. Although I didn't test this specific code, I've done something similar in my code based on the answer linked above, and it works in gcc 4.8.5.

这将按预期调用foo(12,23)。虽然我没有测试这个特定的代码,但是我在我的代码中基于上面链接的答案做了类似的事情,并且它在gcc 4.8.5中工作。

Hmm, I just noticed that this is asking about std::bind, not boost::bind. I don't know what differences there are, if any.

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

#1


21  

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.

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

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.

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

#2


8  

I think you could simulate the behaviour you want using a lambda.

我想你可以使用lambda来模拟你想要的行为。

Something along the lines of this:

有点像这样:

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

EDIT: Just checked, and seems to work fine: http://ideone.com/SPSvi

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

#3


0  

I have two solutions:

我有两个解决方案:

1 - You can overload foo() and have it call the original with defaults:

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

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

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

2 - You can use a static variable as default and then use it in the binding process:

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

#4


-1  

This answer disagrees with R. Martinho Fernandes' answer. You can indeed use boost::bind to bind to the default parameters, you just need to put placeholders in, as so:

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

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

This will call foo(12, 23), as expected. Although I didn't test this specific code, I've done something similar in my code based on the answer linked above, and it works in gcc 4.8.5.

这将按预期调用foo(12,23)。虽然我没有测试这个特定的代码,但是我在我的代码中基于上面链接的答案做了类似的事情,并且它在gcc 4.8.5中工作。

Hmm, I just noticed that this is asking about std::bind, not boost::bind. I don't know what differences there are, if any.

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