gpt4 book ai didi

c++ - 使用 bind() 时,即使不使用 ref() 适配器,参数也会通过引用传递

转载 作者:IT老高 更新时间:2023-10-28 22:37:08 25 4
gpt4 key购买 nike

我有以下 C++11 代码:

#include <iostream>
#include <functional>

using namespace std;
using namespace placeholders;

void f(int a, int b)
{
cout << a << " " << b << endl;
}

void g(int& a, int& b)
{
a *= 2;
b *= 3;
}

int main()
{
int a = 100;
int b = 200;
auto greversed = bind(g,_2,_1);
greversed(b,a);
f(a,b);
greversed(ref(b),ref(a));
f(a,b);
}

基于我对“C++ 编程语言第 4 版”(Stroustrup)的阅读。 968 我希望在第一次调用 greversed(b,a) 期间,a 和 b 的拷贝将通过引用传递给 g(),并且只有第二次调用实际上会通过引用将 a 和 b 传递给 g() .

p 中给出的示例代码。 968:

void incr(int& i)
{
++i;
}

void user()
{
int i =1;
incr(i); // i becomes 2
auto inc = bind(incr,_1);
inc(i); // i stays 2; inc(i) incremented a local copy of i
}

运行这段代码,i 会增加两次,不管评论怎么说。

对于我的程序,我的预期输出是:

100 200
200 600

但是,当我在 Ubuntu 下使用“g++ -std=c++11 test.cpp”编译此代码时,我得到以下输出:

200 600
400 1800

无论是否使用 ref() 适配器,似乎 a 和 b 都是通过引用传递的。

最佳答案

简介

std::placeholders::_* 通过完美转发后来取代它们的类型来工作。

这意味着由于您将 ab(它们是 lvalues)传递给 greversed 这些 < em>左值将被转发g,就像它们一样。


标准 (n3337) 的 [func.bind.bind]p10 部分对此行为进行了说明,但可以在此处找到更易于理解的说明:


困惑的​​来源

我没有读过你所指的书,但你的困惑可能在于 std::bind 在你使用 std::bind 时不会绑定(bind)对传入参数的引用em>非占位符,而是复制参数。

以下示例希望有助于理解使用 std::placeholder 和传入要绑定(bind)的值之间的区别。

int main () {
auto f = [](int& r1, int& r2) {
r1 *= 2;
r2 *= 2;
};

int a = 1;
int b = 2;

auto x = std::bind (f, a, std::placeholders::_1); // a copy of `a` will be stored
// inside `x`

x (b); // pass the copy of `a`, and perfectly-forward `b`, to `f`

std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
}
a: 1
b: 4

关于c++ - 使用 bind() 时,即使不使用 ref() 适配器,参数也会通过引用传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24208582/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com