我想将lambda函数作为回调函数传递给另一个函数:
void test(const std::function<void()> fn){
fn();
}
一切正常,一切正常。但。无论我使用多高的编译器优化级别,它都不会内联它:
proof
当我玩了一段时间后,我发现,使用模板-it变为内联:
template<typename T>
void test2(T fn){
fn();
}
那么......有没有办法让它在没有模板的情况下内联?为什么它变得内联模板声明?只有函数类型作为模板参数传递,而不是函数本身。
答案 0 :(得分:10)
简短的回答:不,没有模板就无法完成这项工作(一般情况下)。原因是源代码中的每个lambda表达式都为该lambda闭包生成唯一类型。 Proof:
auto f1 = [] { return 1; };
auto f2 = [] { return 1; };
static_assert(!std::is_same<decltype(f1), decltype(f2)>::value, "He's wrong");
因此,要接受任意闭包,您必须使用模板或类型擦除包装器(例如std::function
)。当然,类型擦除依赖于运行时多态性,因此它不适合内联。
你可能做这项工作的唯一方法是使用无状态lambda(无捕获),它隐式转换为指向函数的指针。让您的算法将参数作为指向函数的指针,并希望优化器能够深入到内联调用。换句话说,将功能更改为:
void test(void (*fn)()) {
fn();
}