我的问题是扩大这个:Why can lambdas be better optimized by the compiler than plain functions?
再次重申,得出的结论是lambda表达式创建不同专业,其编译器能够平凡的内联,而函数指针是不容易,因为内嵌有一组函数原型的一个专业化。考虑到,将函数指针作为模板,快速为/更快的lambda表达式?
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
template <class F>
int operate(int a, int b, F func)
{
return func(a, b);
}
template <int func(int, int)>
int operateFuncTemplate(int a, int b)
{
return func(a, b);
}
int main()
{
// hard to inline (can't determine statically if operate's f is add or sub since its just a function pointer)
auto addWithFuncP = operate(1, 2, add);
auto subWithFuncP = operate(1, 2, sub);
// easy to inline (lambdas are unique so 2 specializations made, each easy to inline)
auto addWithLamda = operate(1, 2, [](int a, int b) { return a + b; });
auto subWithLamda = operate(1, 2, [](int a, int b) { return a - b; });
// also easy to inline? specialization means there are 2 made, instead of just 1 function definition with indirection?
auto addWithFuncT = operateFuncTemplate<add>(1, 2);
auto subWithFuncT = operateFuncTemplate<sub>(1, 2);
}
所以,如果我能对业绩的比例则排列这些:
operatorFuncTemplate
> = operate<LAMBDA>
> = operate<FUNCTIONPTR>
是否有实例,其中这种关系能够在不平凡的实例失败?
如果编译器可以跟踪“这个函数指针指向这个功能”,编译器可以通过内联函数指针调用。
有时,编译器可以做到这一点。有时,他们不能。
除非你存储在拉姆达函数指针,std::function
,或相似类型擦除包装,编译器在其中拉姆达被称为知道拉姆达类型的地步,所以知道拉姆达的身体。编译器可以平凡内联函数调用。
有关使用函数模板没有改变这一点,除非参数是constexpr
的功能等非类型模板参数:
template <int func(int, int)>
这是这样一个例子。在这里,函数模板,在函数体,是保证在编译时是已知的。
传递func
其他地方,然而,编译器可能会失去它的轨道。
在任何情况下,任何速度差将是高度依赖于上下文的。有时引起的拉姆达的内联较大的二进制文件的大小会造成比无法内联函数指针更加放缓,所以性能可以走另一条路。
喜欢你的任何要求通用正试图使将是错误的时候。