考虑一下守则:
#include <iostream>
#include <algorithm> // std::swap C++98
#include <utility> // std::swap C++11
namespace A
{
template<typename T>
struct Foo {};
template<typename T>
void swap(Foo<T> &lhs, Foo<T> &rhs)
{
std::cout << "A::swap<T>" << std::endl;
}
} /* end namespace A */
namespace std // we explicitly specialize std::swap here
{
template<> // explicit template specialization for std::swap<int>
void swap(A::Foo<int> &lhs, A::Foo<int> &rhs)
noexcept
(is_nothrow_move_constructible<A::Foo<int>>::value && is_nothrow_move_assignable<A::Foo<int>>::value)
{
std::cout << "std::swap<int>" << std::endl;
}
} /* end namespace std */
int main()
{
using std::swap;
A::Foo<int> a, b;
A::Foo<double> x, y;
swap(a, b); // ADL, expected to call std::swap<Foo<int>>, but NO
swap(x, y); // ADL, expected to call A::swap<T>, YES
}我希望std::swap显式专门化在调用swap(a, b)中是一个更好的选择,但是似乎总是倾向于重载A::swap,即输出是:
A:交换A::交换
有人能解释一下为什么会这样吗?
发布于 2015-01-22 00:23:36
显式函数模板的专门化从不更改调用函数模板或重载的函数,只有调用模板的实现。
过载解析忽略专门化(相对于重载,对于不熟悉C++函数模板怪癖的人来说,重载看起来很像部分专门化)。
我可以想象为什么:将重载和模板专门化选择规则混合在一起会使规则更难遵循和正确。
一般来说,对函数模板进行专门化很少是个好主意:重载或分派到模板类通常更好。
请注意,语言谈到了过载解决中的“更专门化”:不要把这与“模板专门化”混淆起来:它们是不同的概念,不幸的是它们共享一个单词。
https://stackoverflow.com/questions/28079317
复制相似问题