c++ - 通常实现 std::swap 重载的基本原理
问题描述
让我们考虑以下最小代码示例:
// Dummy struct
struct S
{
int a;
char * b;
// Ctors, etc...
};
void swap(S & lhs, S & rhs)
{
using std::swap;
swap(lhs.a, rhs.a);
swap(lhs.b, rhs.b);
}
语境
我知道当我们打算调用一个swap()
函数时,正确且推荐的方法是执行以下操作:
// Let's assume we want to swap two S instances.
using std::swap;
swap(s1, s2);
这样,如果有(在给定类型命名空间中定义),ADL 能够找到适当的重载,否则std::swap
使用。
然后我读了一些SO线程:
使用相同的习惯用法(即使对于内置或指针类型),但不仅在我们调用重载时,std::swap()
而且在我们定义它时。
问题
如果成员都是内置类型(或指针类型,可能是指向自定义类型的指针),是否仍然需要/建议使用该习惯用法而不是显式调用std::swap()
?
例如,考虑到我提供的小代码示例,因为S
成员是内置类型,是否可以(格式良好)将其定义如下:
void swap(S & lhs, S & rhs)
{
std::swap(lhs.a, rhs.a);
std::swap(lhs.b, rhs.b);
}
或者也许有一个我看不到的原因仍然需要使用这种using std::swap;
方式?
解决方案
由于 S 成员是内置类型,是否可以将其定义如下(格式正确):[std::swap 用法]
是的。我的意思是,它之所以有效,是因为如果它们都是andstd::swap
,则只需“交换值 a 和 b” ,即内置类型。MoveAssignable
MoveConstructible
如果成员都是内置类型(或指针类型,可能是指向自定义类型的指针),是否仍然有必要/建议使用该习惯用法而不是显式调用 std::swap() ?
只是为了你类的未来:如果有一天它的任何成员被用户定义的类型替换,你可能会忘记修改你的swap
并错过一个“专门的”ADL 实现,仍然调用std::swap
可以(理论上)的泛型效率低下但仍然编译。
boost::swap
实际上,如果您总是自己使用或实现它,您甚至不需要考虑它:
template<typename T> void swap(T& a, T& b) {
using std::swap;
swap(a, b);
}
推荐阅读
- c# - 传递到 ViewDataDictionary 的模型项的类型为“System.Collections.Generic.List”
- node.js - jwt 阻止我查看其他用户的个人资料 nodejs, angular
- python - 连续在另一行上以静止条件运行计数
- javascript - 功能组件发出事件:表达式不可调用 - Vue
- css - 如何在 CSS 中的悬停效果上方显示我的文本?
- android - Android - 获取当前在另一个应用程序中播放的视频的标题/位置/持续时间
- macos - MacOS Sur 从任何地方下载
- php - MYSQL PHP:根据地址列查找重复项
- sql - 如何将大约 5+ 百万个 id 发送到 SQL Server 存储过程以获得相应大小的总和?SQL 2012
- javascript - 按数字长度排序,然后按数字本身