如何解决我应该专门化还是重载在`std::swap` 之类的命名空间中定义的模板?
如果我有一些管理资源的类类型,例如,一个资源,我的类需要定义一个 swap()
函数作为它的接口的一部分来处理该类型的对象,那么我通常会这样做:
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
所以,这是正确的吗?我应该重载还是专门化 RecyclerView
?
解决方法
标准通常不允许在命名空间 std
中添加重载或特化:
[namespace.std]/1 除非另有说明,如果 C++ 程序向命名空间 std
或命名空间 {{ 1}}。
特化类模板有一个例外。您的 std
示例属于以下内容:
[namespace.std]/2 除非明确禁止,否则程序可以将任何标准库类模板的模板特化添加到命名空间 std::hash<Foo>
,前提是 (a) 添加的声明取决于在至少一种程序定义的类型上,并且 (b) 专业化满足原始模板的标准库要求。
您可以重载某些标准库函数外部命名空间 std
,依靠 ADL 来找到它们:
[namespace.std]/7 除了在命名空间 std
或命名空间 std
内的命名空间中,程序可以为任何指定的库函数模板提供重载作为自定义点,前提是 (a) 重载的声明取决于至少一种用户定义的类型,并且 (b) 重载满足自定义点的标准库要求。 [注意:这允许对自定义点的(限定或非限定)调用为给定参数调用最合适的重载。 —结束注释]
std
实际上是一个自定义点。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。