繁体   English   中英

std :: bind和std :: function问题

[英]std::bind and std::function questions

int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
  1. x(123)实际上是否调用了生成std::function的functor的operator() ,而后者又调用了最终调用func std::bind生成的functor的operator() 这是否被优化为与调用func(123)一样最优的东西?
  2. 构造函数在哪里生成std::bind生成的? 在什么范围? std::bind如何命名呢? (可以有名称冲突)
  3. lambda可以替换std::bind所有用法吗?
  4. std::bind是否最适合将其作为lambda实现?
  5. 怎么了std::function的模板参数的语法? 如何解析它以及如何在其他地方使用该模板参数语法?

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

我不会将std::functionoperator()描述为'generated'(它是常规成员),但除此之外这是一个很好的描述。 优化取决于您的编译器,但要注意优化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

1。 x(123)实际上是否调用了生成std::function的functor的operator() ,而后者又调用了最终调用func std::bind生成的functor的operator() 这是否被优化为与调用func(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应该编译为与绑定表达式大致相同。 有一件事我认为 lambdas不能做那个绑定表达式可以nested bind expressions 编辑虽然nested bind expressions的特定习惯用法不能使用lambdas复制,但lambdas当然能够更自然地表达(几乎)相同的内容:

 bind(f, bind(g, _1))(x); 
 // vs.
 [](int x) { f(g(x)); };

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
 {
     // ..
 }

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

C ++ 14将允许lambdas主要替换bind。 特别回应Luc Danton的回答,在C ++ 14中,你可以使用auto编写模板化的lambda,使得bound(0)bound(0L)表现不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM