首页 > 解决方案 > 在没有宏的情况下在 C++ 中执行此部分函数应用程序的“正确”方法是什么?

问题描述

作为一个简化的示例,假设我从以下代码开始:

void function1 (Object &myObject) {
    for (int b = 0; b < 10000; b++) {
        // ... a bunch of code that uses the below myFunction(int, int) in different ways
        auto x = myObject.myFunction(12345, b);
        // do something with x and etc
    }
}

我想要做的是获取 for 循环中的内容,将其放在一个单独的内联函数中,然后调用该函数,并以某种方式授予该函数访问已设置的柯里化版本的myObject.myFunction(a, b)权限b

一种方法是:

__attribute__((always_inline))
inline void function2 (Object &myObject, int &b) {
#define curried(a) myObject.myFunction(a, b)
    // ... a bunch of code that uses the below function in different ways
    auto x = curried(12345);
    // do something with x and etc
}

void function1 (Object &myObject) {
    for (int b = 0; b < 10000; b++) {
        function2(myObject, b);
    }
}

如果您可以使编译器成功 inline function2,则可以生成相同的汇编代码而没有开销。(这可能至少需要 -O1 或 -O2,至少使用 clang,即使__attribute__((always_inline))使用。)

无论哪种方式,在这种情况下使用宏都有些尴尬,并且必须将 from 的值传递bfunction1to function2。将 lambda 函数作为参数传递给 会更好function2,但后来我遇到了捕获问题(您只能传递未捕获的 lambda,但我们需要捕获 myObject),而且一些额外的开销。例如,我想这样做:

__attribute__((always_inline))
inline void function2 (some_type curried) {
    // ... a bunch of code that uses the below function in different ways
    auto x = curried(12345);
    // do something with x and etc
}

void function1 (Object &myObject) {
    for (int b = 0; b < 10000; b++) {
        auto lambda = [&](int a) {return myObject.myFunction(a, n);};
        function2(lambda);
    }
}

但这会失败,除非 lambda 没有捕获,因为没有适合“some_type”的类型。

所以我的问题:

是否有任何正确的方法来做到这一点,它是零开销的,至少有一些最小的优化?

标签: c++optimizationlambdac++17currying

解决方案


一个 lambda 应该做的工作

    auto curried = [&](auto& a) { return myObject.myFunction(a, b);}

或者

    auto curried = [&](const auto& a) { return myObject.myFunction(a, b);}

您是否使用其中一个取决于您的函数是否应该a作为输入输出参数进行修改。myObject如果或b超出之前的范围,您应该小心curried,因为 lambda 将包含一个悬空引用。

另请注意,lambda仅从 C++11 开始可用


推荐阅读