使用按名称调用传递参数

Passing parameters using call by name

本文关键字:参数 调用      更新时间:2023-10-16

假设我有这样的C++片段:

int A[3] = {0, 2, 1};
void f(int x, int y) {
x++; A[1]--; y++;
print(x, y, A[0], A[1], A[2]);
}
void main() {
f(A[0], A[A[1]]);
print(A[0], A[1], A[2]);
}

我想使用按名呼f()传递A[0]A[A[1]]

在这种情况下,打印的结果应该是:1 1 1 2 1 1 2 1(这是我们老师讲授的编程语言课)。但是,我不明白y怎么能成为fprint()的呼吁中的1。y不是在开始和更改为A[A[1]]=A[1]=1之后A[1]--A[A[1]]=A[2]=1绑定吗?在那之后,y++不会让y等于 2?

此外,为了使A[1]A[1]--后成为 2 ,它必须以某种方式增加 1,这正是y++所做的,意思是y++=A[1]++=2.那么,在fprint()的呼唤中,y =/= A[1]

当您在 C++ 中将值传递给函数时,它将成为独立值,并且不再引用数组。因此,y在函数中等于 1,它独立于A['1']

在您的示例中,xy按值传递的,这意味着正在创建值的副本。在f()内部,xy被视为局部变量,对xy所做的任何更改都不会反映回调用方。如果需要,则需要通过引用传递

void f(int &x, int &y)

按名称传递的方法是传递函子而不是单个 (int) 参数:

所以,像这样:

template <typename X, typename Y>
void f(X x, Y y) { // or void f(std::function<int&()> x, std::function<int&()> y)
x()++; A[1]--; y()++;
print(x, y, A[0], A[1], A[2]);
}
int main() {
f([]() -> int&{ return A[0];}, []() -> int&{ return A[A[1]];});
print(A[0], A[1], A[2]);
}

演示

一个丑陋的替代方案是宏:

#define f(x, y) do { (x)++; A[1]--; (y)++; print((x), (y), A[0], A[1], A[2]); } while (0)
int main() {
f(A[0], A[A[1]]);
print(A[0], A[1], A[2]);
}

演示