采用A by值的第一个示例执行两次移动,而refref执行的只移动一次。有什么区别?
struct A
{
A() { cout << "constructor" << endl;}
A(const A&) { cout << "copy constructor " << endl;}
void operator=(const A&) { cout << "assignment operator" << endl; }
A( A&&) { cout << "move copy constructor" << endl;}
void operator=(A&&) { cout << "move assignment operator" << endl;}
};
struct C {
void func(A t) {
d.a = std::move(t);
}
struct Data {
A a;
};
Data d;
};
struct B {
void func(A t) {
C c;
c.func(std::move(t));
}
};
//////////////////////////////////////////////////////////
struct C {
template<class T>
void func(T&& t) {
d.a = std::forward<T>(t);
}
struct Data {
A a;
};
Data d;
};
struct B {
template<class T>
void func(T&& t) {
C c;
c.func(std::forward<T>(t));
}
};
答案 0 :(得分:2)
在功能模板中根据以下配方使用时, 将参数转发给另一个函数,与传递给它完全一样 调用函数。
template<typename T> wrapper(T&& arg) { foo(std::forward<T>(arg)); }
所以在您的代码段中
struct B {
template<class T>
void func(T&& t) {
C c;
c.func(std::forward<T>(t));
}
};
std::foward<T>(t)
只会将T&&
对象转发给c.func()
,与B::func()
完全相同。这不需要移动,这就是使用std::forward<T>
看到更少移动的原因。
我真的建议查看Scott Meyer关于std::move
和std::forward
{{1}}的主题的博文:http://scottmeyers.blogspot.com/2012/11/on-superfluousness-of-stdmove.html