【问题标题】:Understanding std::function and std::bind理解 std::function 和 std::bind
【发布时间】:2013-04-16 09:32:10
【问题描述】:

我在玩 std::function 和 std::bind 时发现一些不直观的东西,我想更好地理解它。

例如:

void fun()
{
}

void hun(std::string) 
{ 
}

int main()
{

   function<void(int)> g = &fun; //This fails as it should in my understanding.

   function<void(int)> f = std::bind(fun); //This works for reasons unknown to me     
   function<void(int, std::string)> h = std::bind(hun); //this doesn't work

return 0;
}

如何将 function&lt;void(int)&gt; 绑定到 void() 函数。 然后我可以调用 f(1) 并获得 fun()。 我想了解这是如何完成的。 进入 Microsoft Visual Studio 2012 的实现让我迷失在无法阅读的宏的海洋中。所以这就是我在这里问这个问题的原因。

【问题讨论】:

  • 我用的是vs2012 Express版。
  • 你能推荐这样一个网站吗?
  • clangg++ 编译。 +1,有趣的情况。
  • @KerrekSB:这是正确的行为——我更想知道 you 用哪个 stdlib 测试了std::bind(fun) 版本,因为那个有问题。 :)

标签: c++ c++11 std-function stdbind


【解决方案1】:

如果您不使用参数占位符(_1_2、...),则传递给从 std::bind 返回的函数对象的任何参数都将被丢弃。与:

std::function<void(int)> f = std::bind(fun, std::placeholders::_1);

如预期的那样,我收到了一个(又长又丑的)错误。

对于对标准语感兴趣的人:

§20.8.9.1.2 [func.bind.bind]

template<class F, class... BoundArgs>
*unspecified* bind(F&& f, BoundArgs&&... bound_args);

p3 返回:具有弱结果类型 (20.8.2) 的转发调用包装器 gg(u1, u2, ..., uM)的效果应为INVOKE(fd, v1, v2, ..., vN, result_of&lt;FD cv (V1, V2, ..., VN)&gt;::type),其中cv代表gcv-限定符以及绑定参数@的值和类型987654331@ 的确定如下所示

p10 绑定参数v1, v2, ..., vN 的值及其对应的类型V1, V2, ..., VN 取决于从调用bind 得到的类型TiDcv调用包装器g 的 em>-qualifiers cv 如下:

  • 如果TiDreference_wrapper&lt;T&gt;,则参数为tid.get(),其类型ViT&amp;
  • 如果is_bind_expression&lt;TiD&gt;::value的值为true,则参数为tid(std::forward&lt;Uj&gt;(uj)...),其类型Viresult_of&lt;TiD cv (Uj...)&gt;::type
  • 如果is_placeholder&lt;TiD&gt;::value的值j不为零,则参数为std::forward&lt;Uj&gt;(uj),其类型ViUj&amp;&amp;
  • 否则,值为tid,其类型ViTiD cv &amp;

【讨论】:

  • 更进一步,即使 std::function f = std::bind(fun);编译。无法实际调用 f: f();编译失败。
  • @PeterR:显然,因为f 的签名要求一个参数。 :)
【解决方案2】:

调用函数模板bind生成的转发调用包装器可以接受任意数量的额外参数;这些将被忽略。 bind 表达式的有效数量和最小签名由其构造中使用的 placeholders 以及它们绑定到的可调用参数确定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2019-02-20
    • 1970-01-01
    • 2014-01-22
    相关资源
    最近更新 更多