std :: function复制参数?

luc*_*nte 9 c++ c++11 std-function

我的代码:

#include <iostream>
#include <functional>
using namespace std;

struct A {
  A() = default;
  A(const A&) {
    cout << "copied A" << endl;
  }
};

void foo(A a) {}

int main(int argc, const char * argv[]) {
  std::function<void(A)> f = &foo;
  A a;
  f(a);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在控制台上看到"复制A"两次.为什么对象被复制两次而不是一次?我怎样才能正确预防?

Luc*_*ton 9

专业化std::function<R(Args...)>有一个带有以下声明的调用操作符:

R operator()(Args...) const;
Run Code Online (Sandbox Code Playgroud)

在您的情况下,这意味着操作员需要A.因此,f(a)由于按值传递语义,调用结果是副本.但是,基础foo目标也按值接受其参数.因此,当参数to f被转发到时,将存在第二个副本foo.

这是设计的,事实上如果A有一个移动构造函数,那么只有一个副本后跟一个移动构造 - 并且调用f(std::move(a))只会导致两个移动构造.如果你觉得这两个副本是太多,你需要重新考虑是否都foof应该采取A的,而不是如A const&,和/或是否A可以有一个明智之举构造.

你也可以不做std::function<void(A const&)> f = &foo;修改foo.但是你应该保留这种情况,因为修改foo是你无法控制的,和/或A廉价的可移动构造不是一种选择.在C++ 11中传递值没有任何问题,所以我建议两者都应该采用A,或者两者都应该采用A const&.