[英]Should I specialize or overload templates defined in a namespace like `std::swap`?
如果我有一些 class 类型来管理例如资源,并且我的 class 需要定义一个swap()
function 作为其接口的一部分,它适用于以下对象:
struct Foo{};
Foo f1, f2;
void swap(Foo& lhs, Foo& rhs){
// code to swap member data of lhs and rhs
}
int main(){
using std::swap;
Foo f1, f2;
swap(f1, f2);
}
现在,我是重载std::swap
还是专门化它?
我了解到,如果我想专门化标准库的函数/类模板,那么我应该打开命名空间std
并在那里声明专门化。 例如:
namespace std{
void swap(Foo&, Foo&);
}
std::hash
专门用于我打算用作无序关联容器的元素类型的类型时,例如std::unordered_map
,我确实专门std::hash
这样:namespace std{ // opening namespace std
template<>
class hash<Foo>{
//...
};
}
那么,这是正确的吗? 我应该重载还是专门std::swap
?
该标准通常不允许在命名空间std
中添加重载或特化:
[namespace.std]/1除非另有说明,否则如果 C++ 程序将声明或定义添加到命名空间
std
或命名空间std
内的命名空间,则它的行为是未定义的。
特化 class 模板有一个例外。 您的std::hash<Foo>
示例属于:
[namespace.std]/2除非明确禁止,否则程序可以将任何标准库 class 模板的模板特化添加到命名空间
std
,前提是 (a) 添加的声明依赖于至少一个程序定义的类型和 (b) 特化满足原始模板的标准库要求。
您可以在命名空间std
之外重载某些标准库函数,依靠 ADL 来找到它们:
[namespace.std]/7除了命名空间
std
或命名空间std
内的命名空间之外,程序可以为任何指定为自定义点的库 function 模板提供重载,前提是 (a) 重载的声明至少取决于用户定义类型和 (b) 重载满足定制点的标准库要求。 [注意:这允许对自定义点进行(合格或不合格)调用,以调用给定 arguments 的最合适的重载。 ——尾注]
std::swap
实际上是一个定制点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.