将移出参数的最佳做法
Best practice for will-move-from parameters
根据核心准则:
F.18:对于"will-move-from"参数,通过X&&&和std::move参数传递
示例为:
void sink(vector<int>&& v) { // sink takes ownership of whatever the argument owned
// usually there might be const accesses of v here
store_somewhere(std::move(v));
// usually no more use of v here; it is moved-from
}
我注意到我倾向于对所有对象使用智能指针,除了廉价复制的对象(我几乎总是只考虑原语(。所以我几乎总是使用以下准则:
void sink(std::unique_ptr<OtherThanPrimitive> p) {
// use p ... possibly std::move(p) onward somewhere else
} // p gets destroyed
我开始考虑我是否使用最佳实践。我能想到的第一种方法的优点是强制函数的调用者显式 std::move,它使代码更干净。在第二种方法中,移动构造函数将被调用两次,但对于智能指针来说,这不是一个很大的成本。考虑到上述情况,我开始考虑改变我的习惯,始终将第一种方法用于我确信支持移动的集合(因此大多数 STL 集合(。自定义对象的第二种方法(我假设考虑为类编写自定义移动构造函数的成本超过了可读性的好处(。是否有任何最佳实践可以涵盖这一点?您通常采用什么方法?我的理由中遗漏了什么吗?
我认为第一种方法的优点是强制函数的调用者显式 std::move,它使代码更干净。在第二种方法中,移动构造函数将被调用两次,但对于智能指针来说,这不是一个很大的成本。
在void sink(T&&)
和void sink(T)
之间:两者都需要仅移动类型或调用移动构造函数的std::move
。第二种形式也可以复制,给定一个可复制的左值参数。如果T
复制不便宜,默默地获得副本可能是一个缺点。与第一种方法相比,第二种形式即使与仅移动类型一起使用,也会在函数参数中具有额外的移动。如果T
移动起来不便宜,那可能是一个缺点。当移动到数据成员中时,或以其他方式在逻辑上复制参数时,第二种形式允许一个重载同时接受 T&& 和 const T& 参数,而不是为每个参数设置一个重载,然后对 N 个参数进行 2^N 个重载。
但是,第二种形式无条件地从论点中移出。第一个可以有条件地离开参数,或者根本不离开参数。呼叫者无法分辨(不好! 第二种形式提供了更清晰的意图表达。
请注意,问题 526 有一个不错的小助手函数copy
您可以将其与第一个表单一起使用,用于不太便宜的可复制类型,以明确复制。使用该帮助程序,您可以默认使用最少的移动次数进行移动,并选择加入显式复制。签名提供的意图仍然不如第二种形式那么清晰。
考虑到上述情况,我开始考虑改变我的习惯,始终将第一种方法用于我确信支持移动的集合(因此大多数 STL 集合(。自定义对象的第二种方法
我不认为自定义对象与支持移动的集合是正确的区别。如果T
不可移动,则应const T&
或T
参数(如果需要副本(。在这种情况下使用第一种形式是没有意义的。
如果T
是可移动的,根据经验,请使用核心准则。使用第一种形式。如果T
是廉价的,请使用第二种形式。
我假设考虑为类编写自定义移动构造函数的成本超过了可读性的利润
不需要为大多数类编写自定义移动构造函数。存储由某些东西拥有。这需要一个自定义移动构造函数。指向存储的内部簿记会产生对自定义移动构造函数的需求。所以,容器。如果你正在编写一个容器,用于与提供的类型一起通用,如果它可以更有效,则可能应该编写一个移动构造函数。否则可能会更令人惊讶。
- 将字符移出范围的危险
- 将移出参数的最佳做法
- 是否可以将值分配给移出位置?
- 将键移出 std::map<> &&
- 移出某些元素后无法从矢量中删除
- 当鼠标移出窗口时,SFML 窗口会自行关闭
- 虚拟析构函数将对象移出 rodata 部分
- 将代码移出类定义时未扩展参数包
- 如何将变量从 for 循环中移出?
- 在移出向量上调用 size() 方法是否安全?
- 从移出对象移动
- 在 2D 阵列板中移动并防止玩家移出板
- 可以将std::getline()与从std::string中移出的字符串一起使用吗
- 是否可以将 std::move 对象移出函数?(C++11).
- 是否应将移出对象保留为"safe"状态?
- 如何将unique_ptr移出矢量<Foo><unique_ptr>?
- 如何使用默认移动构造函数将数据移出范围
- 移出 C++11 中 std priority_queue 元素
- 头文件中定义的多个结构 - 我是否应该将它们移出单独的 h 和 cpp 文件中
- 将资源移出泛型类