c++ - 在没有宏的情况下在 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 的值传递b
给function1
to 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
作为输入输出参数进行修改。myObject
如果或b
超出之前的范围,您应该小心curried
,因为 lambda 将包含一个悬空引用。
另请注意,lambda仅从 C++11 开始可用
推荐阅读
- mysql - mysql bind-address vs mysqlx-bind-address 设置以允许远程连接
- json - 在 console.log 中出现错误,显示“位置 1 的 JSON 中出现意外的令牌 o”
- sql-server - 如何使用带有 over 子句或其他选项的 Ceiling 函数来获得 ceil 值
- r - 将每个进程的闪亮会话数限制为 1
- python - 使用python函数从字符串中提取参数
- sas - 将变量移动到 SAS 中的下一列
- vb.net - 从 TimeSpan 仅计算小时分钟秒
- node.js - 如何使用 mongoose 将我的 socket.io 连接到我现有的 mongodb 连接
- python - 如何提取numpy数组的特定部分?
- android - Recyclerview 不刷新