一个选择是让你的超载比其他选择“更差的匹配”。然后,只有当它们尚不存在时才会选择您的版本:
#if 0
#include <algorithm>
using std::swap;
#endif
template <typename T>
struct ForceLessSpecialized {
typedef T TYPE;
};
template <typename T>
void swap (T &, typename ForceLessSpecialized<T>::TYPE &) {
}
void bar () {
int i;
swap (i, i);
}
发生了什么:
当有两个候选函数模板特化时,编译器执行“函数模板的部分排序”('03 14.5.5.2)。这将检查一个模板的函数模板参数是否可用于专门化另一个模板。
对于每个模板,我们将使用虚拟参数T1
and T2
我们使用这些类型创建虚拟参数列表:
// std::swap argument list
( T1 & , T1 & )
// our swap argument list
( T2 &, typename ForceLessSpecialized<T2>::TYPE & )
使用来自的虚拟参数专门化我们的交换std::swap
gives:
Deduction from First parameter: T == T1
Deduction from Second parameter: Non Deduced Context
推导出来的T
is T1
并且推演成功。
专精std::swap
使用交换的虚拟参数给出:
Deduction from First parameter: T == T2
Deduction from Second parameter: T == ForceLessSpecialized<T2>::TYPE
推导的类型为T
不一样,所以这被认为是推演失败。
因此,综合论证std::swap
可以用来专门化我们的模板,但是我们模板的合成参数不能用来专门化std::swap
. std::swap
被认为更专业,因此赢得了部分排序。