了解std :: function和std :: bind

时间:2013-04-23 08:42:14

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

我正在玩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<void(int)> 绑定到 void()的函数。 然后我可以调用f(1)并获得乐趣()。 我想了解这是如何完成的。 进入Microsoft Visual Studio 2012的实现,让我迷失在无法理解的宏海中。所以这就是我在这里提出这个问题的原因。

2 个答案:

答案 0 :(得分:8)

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

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

我得到了一个(长而丑陋的)错误。

对于对Standardese感兴趣的人:

§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<FD cv (V1, V2, ..., VN)>::type),其中 cv 表示g cv - 限定符以及值和绑定参数v1, v2, ..., vN的类型按照以下规定确定

     

p10绑定参数v1, v2, ..., vN及其对应类型V1, V2, ..., VN 的值取决于从TiD 调用派生的bind类型和调用包装器g cv - 限定符 cv 如下:

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

答案 1 :(得分:6)

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