1 . x(123)
实际上调用了由 std::function
生成的函数对象的 operator()
,该函数对象进而调用了由 std::bind
生成的函数对象的 operator()
,最终调用了 func
。这个过程是否会被优化成和直接调用 func(123)
一样优秀的结果?
如果启用了优化,则 'stuff' 将被内联,您可以确保这与直接调用 func(123)
一样优秀。
2 . std::bind
生成的函数对象存在于哪个作用域中?它的名称是如何命名的?(是否可能存在名称冲突)
具体而言,bind
生成一个瞬时的、实现定义的 bind 表达式,可分配给 function<>
。Function 只是一个类模板(感谢 Luc T.)。它位于标准库中。但是,bind 表达式是实现定义的。
标准库确实带有特性(
std::is_bind_expression<>
),允许MPL检测此类表达式。与std::function相比,bind表达式的一个决定性特征是它们是所谓的“延迟可调用对象”(即它们保留完整的调用站点语义,包括在实际应用站点上选择重载的能力)。另一方面,
std::function<>
则承诺单个原型,并通过类型擦除(
类似于variant
或any
)内部存储
可调用对象。
3 .lambda表达式能否替代std::bind的所有用途?
4 .将std::bind实现为lambda表达式是否和std::bind一样优化?
AFAICT,lambda表达式应该编译成与绑定表达式大致相同的代码。我认为lambda表达式无法完成绑定表达式可以完成的
嵌套绑定表达式
的一件事。
编辑 虽然无法使用lambda表达式复制嵌套绑定表达式的特定习惯用法,但是lambda表达式当然能够更自然地表达(几乎)相同的内容:
bind(f, bind(g, _1))(x);
// vs.
[](int x) { f(g(x)); };
5. std::function
模板参数的语法是什么?它是如何解析的,我该如何在其他地方使用该模板参数语法?
这只是一个函数签名(函数的类型),作为模板参数传递。
您也可以将其用作函数参数类型,它会退化为函数指针(类似于按值传递数组参数如何退化为指针,感谢 David!)。
实际上,在大多数情况下,只要您不需要
命名变量/类型,就可以在任何地方使用它。
void receiveFunction(void(int, double));
void sample(int, double) { }
int main()
{
receiveFunction(sample);
}
void receiveFunction(void (*f)(int, double))
{
}
function<>
的参数)到行为(bind
的结果在哪里?能否用 lambda 替代?)再到性能(是否会被优化?)的范围。 - David Rodríguez - dribeas