【问题标题】:Can I bind to a function that takes default arguments and then call it?我可以绑定到采用默认参数的函数然后调用它吗?
【发布时间】:2012-05-29 22:41:17
【问题描述】:

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

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

}

【问题讨论】:

  • 定义“不起作用”。如果您为变量指定不同的名称,则代码将编译。
  • 你为什么一直重新分配给 f?
  • @R.MartinhoFernandes 是的,抱歉,示例不完整。更新代码
  • @111111 这更像是一种象征意义。更新代码

标签: c++ c++11 bind default-arguments


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    类似这样的事情:

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

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

    【讨论】:

      【解决方案3】:

      我有两个解决方案:

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

      【讨论】:

        【解决方案4】:

        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。我不知道有什么区别,如果有的话。

        【讨论】:

        • “虽然我没有测试这个特定的代码”解释了为什么这在 GCC 4.8.5(或任何其他版本)和任何版本的 Boost(从 1.49.0 到 1.64. 0)。您引用的“这个答案”确实不是说您可以调用绑定表达式没有默认参数,而是说明您可以绑定特定值或需要传递参数。 R. Martinho Fernandes 的回答是正确的,您不能以这种方式调用绑定表达式(既不使用 boost:bind 也不使用 std::bind)。
        猜你喜欢
        • 2023-01-24
        • 2010-09-17
        • 2015-05-19
        • 2011-03-28
        • 1970-01-01
        • 2022-12-11
        • 1970-01-01
        • 2011-04-01
        相关资源
        最近更新 更多