没有模板的 C++11 内联 lambda 函数

标签 c++ c++11 lambda

我想将 lambda 函数作为回调传递给另一个函数:

void test(const std::function<void()> fn){
    fn();
}

它工作正常,一切正常。但。无论我使用多高的编译器优化级别,它都不会内联它:
proof

当我玩了一段时间后,我发现使用模板 - 它变成了内联:

template<typename T>     
void test2(T fn){
     fn();
}

proof_2

那么...有没有办法让它在没有模板的情况下内联?以及为什么它与模板声明内联?只有函数类型作为模板参数传递,而不是函数本身。

最佳答案

简短回答:不,如果没有模板(在一般情况下),您将无法完成这项工作。原因是源代码中的每个 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();
}

关于没有模板的 C++11 内联 lambda 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21407691/

相关文章:

c++ - 检查单选按钮状态 winapi

c++ - 在可变参数模板中使用 lambda 调用 std::make_tuple - 这应该在 C++11 中工作吗?

qt - QSignalSpy 没有捕捉到信号

powershell - 在 PowerShell 中异步调用 System.Action 实例

java - 如何将函数引用传递到我的方法中并使用它们?

c# - 为什么 C# 编码字符串不能与 C++ DLL 一起使用

C++ 移动构造函数 - C++ 之旅

支持 .h .cpp 同步的 C++ 源代码文本编辑器

c++ - 什么时候添加 move 构造函数和 move 赋值运算符才会真正开始有所作为?

java - Jmockit 中的 Lambda 期望