c++ - 是否有合理的替代重载和完美转发?
问题描述
如果我通过复制/移动接受一个值然后对其执行移动,它似乎复制了 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
}
解决方案
可能最通用和最有效的解决方案是使用完美转发:
template <typename... Ts>
void useA2(Ts&&... vs)
{
A a1 { std::forward<Ts>(vs)... };
}
然后,useA2(a1);
将只调用一个复制构造函数,而无需任何不必要的移动。
推荐阅读
- javascript - 使用 data() 中的字段作为图表数据 - FusionCharts
- java - 在 JavaFX 中移动多个场景
- python - 建议的通过python加密的方法
- python - Spark DataFame:JDBC 写入自动生成的字段
- python - Kivy ScrollView TypeError 的问题:add_widget() 需要 2 到 3 个位置参数,但给出了 4 个
- pyspark - dask - 在大于 RAM 的大型数据帧上应用函数
- c - 一段时间内切换无法正常工作。即使选择!=0,while 也会立即终止
- python - ImportError:无法导入名称 BeatifulSoup
- swift - 使用 SwiftyJSON 将 JSON 解析为结构
- javascript - 将前一个兄弟复制到剪贴板