我应该专门化或重载在诸如"std::swap"之类的命名空间中定义的模板吗
Should I specialize or overload templates defined in a namespace like `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::unordered_map
(的元素类型的类型专门化std::hash
时,我确实以这种方式专门化了std::hash
:
namespace std{ // opening namespace std
template<>
class hash<Foo>{
//...
};
}
那么,这是正确的吗?我应该重载还是专用std::swap
?
该标准通常不允许在命名空间std
:中添加重载或专业化
[namespace.std]/1除非另有说明,否则如果C++程序向命名空间
std
或命名空间std
中的命名空间添加声明或定义,则其行为是未定义的。
专门化类模板有一个例外。您的std::hash<Foo>
示例属于以下类别:
[namespace.std]/2除非明确禁止,否则程序可以将任何标准库类模板的模板专用化添加到命名空间
std
,前提是(a(添加的声明取决于至少一个程序定义的类型,并且(b(专用化满足原始模板的标准库要求。
您可以在命名空间std
外重载某些标准库函数,并依赖ADL来找到它们:
[namespace.std]/7除了在命名空间
std
或命名空间std
内的命名空间中,程序可以为指定为自定义点的任何库函数模板提供重载,前提是(a(重载的声明取决于至少一个用户定义的类型,并且(b(重载满足定制点的标准库要求。[注意:这允许对自定义点进行(限定或非限定(调用,为给定的参数调用最合适的重载。--end Note]
std::swap
实际上是一个自定义点。
相关文章:
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- CUDA内核和数学函数的显式命名空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 是否可以将函数导入命名空间,但不能导出它?
- C++ C++类中的命名空间降级
- 如何使用 soong 命名空间来有条件地编译模块
- 使用 Clang++ 有没有办法将文件作为命名空间等包含?
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何通过命名空间调用非静态方法
- 在命名空间名称之前加上 :: 是什么意思?