在没有宏的情况下C++执行此部分函数应用程序的"right"方法是什么?

What is the "right" way to do this partial function application in C++ without a macro?

本文关键字:应用程序 函数 right 方法 是什么 此部 情况下 执行 C++      更新时间:2024-09-27

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

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);
}
}

如果您能让编译器成功地内联function2,那么就可以在没有开销的情况下生成相同的汇编代码。(即使使用__attribute__((always_inline)),也可能至少需要-O1或-O2,至少需要clang。(

无论哪种方式,在这种情况下使用宏都有点尴尬,并且必须将b的值从function1传递到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">

所以我的问题是:

是否有任何正确的方法可以做到这一点,即零开销,至少需要一些最小的优化?

lambda应该完成的工作

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

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

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

还要注意,Lambda仅在C++11 之后才可用