如果我通过复制/移动接受一个值,然后对其进行移动,则似乎要复制LValues并移动RValues。
在两种情况下,此代码都能正确有效地执行吗?
为useA2()创建RValue和LValue重载,还是将useA2函数转换为模板以使用转发,这是否是合理的选择?
struct A
{
int *buff;
A() { cout << "A::constructor\n"; buff = new int[1000]; } //expensive
A(const A& a) { cout << "A::copy constructor\n"; buff = new int[1000]; memcpy(buff, a.buff, 1000); }
A(A&& a) { cout << "A::move constructor\n"; buff = a.buff; a.buff = nullptr; }
~A() { cout << "A::destructor\n"; delete buff; }
};
A getA()
{
A temp; // without temp, compiler can perform copy elision, skipping copy/move constructors
return temp;
}
void useA2(A a)
{
A a1 = std::move(a);
}
void demo()
{
A a1;
//useA2(getA()); // performs 2 moves
useA2(a1); // performs a copy to the input param, then moves the copy
}
答案 0 :(得分:2)
最通用,最有效的解决方案是使用完美转发:
template <typename... Ts>
void useA2(Ts&&... vs)
{
A a1 { std::forward<Ts>(vs)... };
}
然后,useA2(a1);
将只调用一个副本构造函数,而不会进行任何不必要的动作。