My code:
#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”。为什么对象被复制两次,而不是一次?我该如何正确预防这种情况?
专业化std::function<R(Args...)>
有一个带有以下声明的调用运算符:
R operator()(Args...) const;
在你的情况下,这意味着操作员需要A
。因此,调用f(a)
由于按值传递语义,会产生副本。然而,底层foo
target 也按值接受其参数。因此,当参数传递给f
被转发到foo
.
这是设计使然,事实上如果A
如果有一个移动构造函数,那么只有一个副本,后面跟着一个移动构造函数 - 并且调用f(std::move(a))
只会导致两次移动结构。如果您觉得两份副本太多,您需要重新考虑是否两者都foo
and f
应该采取A
而不是例如A const&
,和/或是否A
可以有一个合理的移动构造函数。
你也可以做std::function<void(A const&)> f = &foo;
不修改foo
。但你应该保留它以备修改的情况foo
超出您的控制范围,和/或使A
廉价地移动建造不是一个选择。没有什么问题按值传递 https://stackoverflow.com/questions/7592630/is-pass-by-value-a-reasonable-default-in-c11/7592741在 C++11 中,所以我建议两者都应该采用A
,或者两者都应该采取A const&
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)