std :: bind和std :: function问题

Dav*_*vid 11 c++ c++11

int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
Run Code Online (Sandbox Code Playgroud)
  1. x(123)实际上是否调用了生成operator()的仿函数,std::function而仿函数又调用了生成的最终调用operator()的仿函数?这是否被优化为最佳调用?std::bindfuncfunc(123)
  2. 算子生活在哪里std::bind生成?在什么范围?怎么std::bind命名呢?(可以有名称冲突)
  3. lambda可以取代所有用途std::bind吗?
  4. std::bind取而代之的是将它作为lambda实现的最佳选择?
  5. 怎么了模板参数的语法std::function?如何解析它以及如何在其他地方使用该模板参数语法?

Luc*_*ton 16

x(123)实际上是否调用了生成std :: function的functor的operator(),而后者又调用了最终调用func的std :: bind生成的functor的operator()?这是否被优化为与调用func(123)一样最优的东西?

我不会形容operator()std::function是"产生"(这是一个普通成员),但除此之外,这是一个很好的说明.优化取决于您的编译器,但要注意优化间接std::function(需要使用类型擦除),编译器可能需要执行英雄.

构造函数在哪里生成std :: bind生成的?在什么范围?std :: bind如何命名呢?(可以有名称冲突)

调用std::bind返回未指定类型的仿函数,该仿函数的副本存储在x对象内.该副本将与其x本身一样长.没有名字涉及,所以我不确定你的意思.

lambda可以替换std :: bind的所有用法吗?

不,请考虑auto bound = std::bind(functor, _1);哪里functor是一个超载的类型operator(),让我们说longint.然后bound(0L)没有相同的效果bound(0),你不能用lambda复制它.

std :: bind是否最适合将其作为lambda实现?

这取决于编译器.衡量自己.

怎么了std :: function的模板参数的语法?如何解析它以及如何在其他地方使用该模板参数语法?

这是一种功能类型.也许你已经熟悉指针/函数引用的语法:void(*)(), int(&)(double). 然后只需删除类型中的指针/引用,您就可以使用函数类型:void(),int(double).你可以使用这样的:

typedef int* function_type(long);
function_type* p; // pointer to function
Run Code Online (Sandbox Code Playgroud)

  • +1是问题#2的唯一正确答案:仿函数只是一个对象,没有神奇的类生成. (2认同)

seh*_*ehe 6

1.x(123)实际上是否调用了生成operator()的仿函数,std::function而仿函数又调用了生成的最终调用operator()的仿函数?这是否被优化为最佳调用?std::bindfuncfunc(123)

如果你启用了优化,那么'stuff'会被内联,你可以指望这是最好的调用func(123).

2.算子生活在哪里std::bind生成?在什么范围?怎么std::bind命名呢?(可以有名称冲突)

精确:bind生成一个"转瞬即逝",实现定义,绑定表达式,可分配给function<>.功能只是一个类模板(谢谢,Luc T.).它存在于标准库中.但是,绑定表达式是实现定义的.

标准库附带性状(std::is_bind_expression<>),以允许这样的表达式的MPL检测.绑定表达式在std :: function上的一个决定性特征是它们(我称之为)延迟可调用对象(即它们保留完整的调用站点语义,包括在实际应用程序站点选择重载的能力).std::function<>另一方面,提交单个原型并通过类型擦除(思考)在内部存储可调用对象.variantany

3.lambda可以替换std :: bind的所有用法吗?

4.std :: bind是否最适合将其作为lambda实现?

AFAICT lambdas应该编译为与绑定表达式大致相同.有一两件事,我觉得 lambda表达式不能这样做绑定表达式可以编辑在嵌套绑定表达式的具体使用成语lambda表达式是不是可复制的,lambda表达式是当然能够表达(几乎)相同的更自然:nested bind expressions

 bind(f, bind(g, _1))(x); 
 // vs.
 [](int x) { f(g(x)); };
Run Code Online (Sandbox Code Playgroud)

 

5.怎么了模板参数的语法std::function?如何解析它以及如何在其他地方使用该模板参数语法?

它只是一个函数签名(函数的类型),作为模板参数传递.

您还可以将它用作函数参数类型,它会降级为函数指针(类似于数组按值参数降级为指针的方式,感谢David!).在实践中,大多数地方,只要您不需要命名变量/类型:

 void receiveFunction(void(int, double)); // spunky 'function<>'-style syntax

 void sample(int, double) { } 

 int main()
 { 
     receiveFunction(sample);
 }

 void receiveFunction(void (*f)(int, double)) // boring 'old' style syntax
 //                   void ( f)(int, double)  // ... also ok
 {
     // ..
 }
Run Code Online (Sandbox Code Playgroud)