可能重复:
如何为我的班级提供交换功能?
每次我认为我理解它,我都会看到让我感到困惑的事情.
如果您想swap为自己的课程提供实施,您会怎么做?
可能性列表如下:
在std命名空间中定义一个(带两个参数),在下面调用#3
(有人说这是正确的;有些人说非法)
在类中定义一个静态方法,接受两个参数交换
(对我来说比#4更有意义,但我不明白为什么没有人这样做),它会swap根据需要调用任何基类
定义一个实例方法的类的内部,采取一个其他参数与交换,它调用任何基础类swapS作为必要
定义一个实例方法的类中,以2个其它参数来交换,也这里,任何基础类这就要求swapS作为必要
还有别的
我自己的理解是,我需要#5,#3,凡来电将被调用swap一样using std::swap; swap(a, b);,但似乎没有人认为联合是真正困惑我的事实.我真的根本不理解#4,因为实际上每个人似乎都在使用实例成员,而实际操作是静态的.我无法分辨我的理解是错误的还是我在查看时看到的一堆答案.
什么是正确的方法?
C++11 标准说一个对象t可以与一个对象交换,u如果swap(t, u)并且swap(u, t)是swap从重载集中选择调用的非成员函数的有效表达式,该重载集中包括两个std::swap模板<utility>和参数依赖查找找到的任何重载,这样的值t并被u交换。
在上述条件下交换两个对象的常规方法是:
using std::swap;
swap(t, u);
Run Code Online (Sandbox Code Playgroud)
这里名称查找将考虑ADL 发现的std::swap任何重载swap,然后重载解析将选择最佳匹配。
考虑您的每个实现:
向 namespace 添加重载是不合法的std,而且上面的规则并不要求无论如何都要找到它们。std::swap如果特化是针对用户定义的类型(即不是标准库类型或基本类型),则特化标准函数模板是合法的。如果特化std::swap它是有效的,否则无效,并且您不能部分特化函数模板.
将找不到静态成员函数,swap(t, u)因为它需要被限定,例如Foo::swap(t, u)
一元swap成员函数不能被称为 as swap(t, u),它必须被称为t.swap(u)
您提供的链接显示了一个非成员 friend函数,可以由 ADL 找到,因此可用于使类型可交换。
这样的功能可以通过ADL找到。
所以 2 和 3 不会使类型可交换。4个,5个。1 可能会,如果做得正确,但不能用于交换类模板。
3 不是必需的,但可用于帮助实现 4 或 5,因为成员函数将可以访问类型的内部详细信息,因此可以交换私有成员。对于 4,该函数是朋友,因此已经具有访问权限。因此,通过排除过程你需要要么4或3和5一般认为更好的是提供一种构件交换(3),然后在相同的命名空间(5),其调用部件交换提供非成员函数。
根据您自己的理解,我见过的常见模式是提供3和5.
std::命名空间添加了一个特殊化,这是允许的,但在所有情况下可能都不可能(如果你的类型是模板本身).swap类型保持为成员的其他类型的实现,他们将需要限定调用(void swap( other& l, other& r ) { T::swap( l.t, r.t ); })rvalues 一起使用(即使在C++ 03中)并且在某些情况下是惯用的std::vector<int>().swap( v );以清除向量的内容.void swap( other& l, other& r ) { using std::swap; swap( l.t, r.t ); }而无需知道other::t具有特定swap重载的类型或std::需要使用的类型.转发到3允许您提供可以通过ADL以及临时对象使用的单个(实际)实现.| 归档时间: |
|
| 查看次数: |
9633 次 |
| 最近记录: |