Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用bind()时,即使未使用ref()适配器,参数也是通过引用传递的_C++_C++11 - Fatal编程技术网

C++ 使用bind()时,即使未使用ref()适配器,参数也是通过引用传递的

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;

我有以下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);
}
运行这段代码时,无论注释怎么说,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;
}