std :: function复制参数? [英] std::function copying parameters?

查看:220
本文介绍了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;
}

我在控制台上看到复制的A两次。为什么对象被复制两次,而不是一次?如何正确防止这种情况?

I'm seeing "copied A" twice on the console. Why is the object being copied twice, not once? How can I prevent this properly?

推荐答案

专业化 std :: function< R 。)> 具有具有以下声明的调用运算符:

The specialization std::function<R(Args...)> has a call operator with the following declaration:

R operator()(Args...) const;

在这种情况下,这意味着操作符 A 。因此,调用 f(a)会导致由于按值传递语义的副本。但是,底层的 foo 目标也通过值接受其参数。因此,当 f 的参数被转发到 foo 时,会有第二个副本。

In your case, this means that the operator takes A. As such, calling f(a) results in a copy due to the pass-by-value semantics. However, the underlying foo target also accepts its argument by value. Thus there will be a second copy when the parameter to f is forwarded to foo.

这是通过设计,事实上如果 A 有一个移动构造函数,只有一个副本后面跟着一个移动构造 - f(std :: move(a))只会导致两个移动构造。如果你认为两个副本太多,你需要重新考虑 foo f 是否应该 A 而不是eg A const& ,和/或 A 可以有一个明智的移动构造函数。

This is by design, and in fact if A had a move constructor there would be only one copy followed by a move construction -- and calling f(std::move(a)) would only result in two move constructions. If you feel that two copies are too much you need to reconsider whether both foo and f should take A instead of e.g. A const&, and/or whether A can have a sensible move constructor.

你也可以做 std :: function< void(A const&)> f =& foo; ,而不修改 foo 。但是你应该保留修改 foo 超出你的控制,和/或使 A 不是一个选项。 传递值没有任何问题在C ++ 11中,所以我建议或者两者都应该 A ,或者两者都应该 A const&

You can also do std::function<void(A const&)> f = &foo; without modifying foo. But you should reserve that for the case where modifying foo is beyond your control, and/or making A cheaply move constructible is not an option. There is nothing wrong with passing by value in C++11, so I suggest that either both should take A, or both should take A const&.

这篇关于std :: function复制参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆