C++ 使用bind()时,即使未使用ref()适配器,参数也是通过引用传递的
我有以下C++11代码:C++ 使用bind()时,即使未使用ref()适配器,参数也是通过引用传递的,c++,c++11,C++,C++11,我有以下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;
#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);
}
运行这段代码时,无论注释怎么说,i都会递增两次
对于我的程序,我的预期输出是:
100 200
200 600
然而,当我在Ubuntu下使用“g++-std=c++11 test.cpp”编译这段代码时,我得到了以下输出:
200 600
400 1800
无论是否使用ref()适配器,似乎a和b都是通过引用传递的。Introduction
std::占位符::。*
通过完美地转发稍后取代它们的类型来工作
这意味着,由于您正在将a和b(它们是左值)传递给g,这些左值将被转发到g
,与它们完全相同
此行为在标准()的
[func.bind.bind]p10节中进行了解释,但在这里可以找到更容易理解的解释:
混乱之源
我没有读过您所指的书,但您的困惑可能在于,当您使用非占位符时,std::bind
不会将引用绑定到传入的参数,而是复制该参数
下面的示例有助于理解使用std::占位符和传入要绑定的值之间的区别
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和b的副本?bind返回的函数只需要两个references@chris这让我很惊讶,我编辑了原始问题,并添加了Stroustrup书中的示例代码。也许只是作者的一个错误?正如在接受的答案中指出的那样,占位符参数不需要ref()适配器。是的,它看起来像书中的一个bug,并且似乎没有在其中列出。谢谢Filip!完美的
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;
}