内联lambda具有相同的函数指针间接寻址延迟

时间:2017-01-05 14:00:12

标签: c++ c++11 lambda

// approach 1
template <typename T>
void f1(T t, int a, int b) {
   t(a, b);
}

// approach 2
void f2(void(*g)(int, int), int a, int b) 
{
   g(a, b); 
}

void g (int a, int b) 
{
    // do something
}

int main() 
{
   f1([](int a, int b)
         { 
           //do something 
         }, 1, 2);

   f2(&g, 1, 2);
}

我的问题是,f1f2是否遭受相同的间接寻址延迟以获取要执行的函数的地址(假设lambda是作为函数对象实现的)?

如果lambda不是内联怎么办?

注意:我将函数f1声明为模板,以便将参数lambda类型的推论留给编译器(例如,不是强制执行std函数,不确定它是否会产生影响)。

2 个答案:

答案 0 :(得分:5)

从概念上讲,编译器应该能够内联lambda体。使用lambda是一个编译时间,这意味着编译器确切地知道你要调用哪个函数,因此它应该能够内联代码。使用函数指针传递的函数直到运行时才真正知道,因此编译器还有很多工作要做,以便尝试查看是否可以内联它。通常,代码没有内联,并且您通过指针有间接。

答案 1 :(得分:3)

  

f1和f2是否遭受相同的间接寻址延迟以获取要执行的函数的地址(假设lambda是作为函数对象实现的)?

标准没有规定任何有关延迟的保证。但是,lambda调用没有任何理由比调用常规内联函数有更多的延迟。编译器可以在编译时确定生成函数的地址,并且不需要间接。

调用函数指针可能需要间接开销,除非函数已内联扩展,在这种情况下,指针的值可以在扩展上下文中的编译时知道。

  

如果lambda不是内联怎么办?

您不能声明lambda,并在另一个编译单元中定义它。所有lambdas都是内联的。

  

注意:我将函数f1声明为模板,以便将参数lambda类型的推论留给编译器(例如,不是强制执行std函数,不确定它是否会产生影响)。

std::function至少具有与函数指针一样多的开销。