int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
x(123)
是否实际调用operator()
生成的仿函数的std::function
,而operator()
依次调用最终调用的std::bind
生成的仿函数func
func(123)
?这是否被优化为与调用std::bind
一样最优的东西?std::bind
生成的仿函数在哪里生活?在什么范围? std::bind
如何命名呢? (可以有名称冲突)std::bind
的所有用途吗?std::function
最适合将其作为lambda实现吗?答案 0 :(得分:16)
x(123)实际上是否调用了生成std :: function的仿函数的operator(),而该函数又调用了最终调用func的std :: bind生成的仿函数的operator()?这是否被优化为调用func(123)最优的东西?
我不会将operator()
std::function
描述为'生成'(它是常规成员),但除此之外这是一个很好的描述。优化取决于您的编译器,但要注意优化std::function
的间接(需要使用类型擦除),编译器可能需要执行英雄。
std :: bind生成的函子在哪里?在什么范围? std :: bind如何命名呢? (可以有名称冲突)
对std::bind
的调用返回一个未指定类型的仿函数,该仿函数的副本存储在x
对象中。此副本将与x
本身一样长。没有名字涉及,所以我不确定你的意思。
lambdas可以替换std :: bind的所有用法吗?
没有。考虑auto bound = std::bind(functor, _1);
其中functor
是一个带有重载operator()
的类型,比如说long
和int
。然后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 :(得分:6)
1。
x(123)
是否实际调用了operator()
生成的仿函数的std::function
,而仿函数又调用了仿函数的operator()
生成std::bind
,最终调用func
?这是否被优化为与调用func(123)
一样最优的东西?
如果您启用了优化功能,则“内容”会被内联,您可以指望这与调用func(123)
一样最佳。
2。
std::bind
生成的仿函数在哪里?在什么范围?std::bind
如何命名呢? (可以有名称冲突)
精确:bind
生成一个“转瞬即逝”的实现定义绑定表达式,可分配给function<>
。功能只是一个类模板(谢谢,Luc T.)。它存在于标准库中。但是,绑定表达式是实现定义的。
标准库 带有特征(std::is_bind_expression<>
)以允许MPL检测此类表达式。绑定表达式在std :: function上的一个决定性特征是它们(我称之为)延迟可调用对象(即它们保留完整的调用站点语义,包括在实际中选择重载的能力申请网站)。另一方面,std::function<>
提交单个原型并在内部存储callable object类型擦除( think variant
或any
)。
3. Lambda可以替换std :: bind的所有用法吗?
4。 std :: bind是最佳实现,而不是将其作为lambda实现吗?
AFAICT lambdas应该编译为与绑定表达式大致相同。我认为 lambdas无法做到的一件事就是可以 nested bind expressions
编辑虽然嵌套绑定表达式的特定习惯用法不能使用lambdas复制,但lambdas当然能够更自然地表达(几乎)相同的内容:
bind(f, bind(g, _1))(x);
// vs.
[](int x) { f(g(x)); };
5.
std::function
的模板参数的语法是什么?如何解析它以及如何在其他地方使用该模板参数语法?
它只是一个函数签名(函数的 type ),作为模板参数传递。
您也可以将它用作函数参数类型,降级到函数指针(类似于数组按值参数降级为指针的方式,感谢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
{
// ..
}
答案 2 :(得分:0)
lambdas可以替换std :: bind的所有用法吗?
C ++ 14将允许lambdas主要替换bind。特别回应Luc Danton的答案,在C ++ 14中,你可以使用auto编写模板化的lambda,使bound(0)
和bound(0L)
的行为不同。