std :: hash模板部分特化

use*_*730 9 c++ templates std language-lawyer c++11

我用模板写了一些类:

 template <class T, class Allocator = ::std::allocator<T> >
 class my_list;
Run Code Online (Sandbox Code Playgroud)

我应该为这个类编写:: std :: hash specializtion.我怎样才能做到这一点?简单的部分专业化:

namespace std {
  template <class T, class Allocator>
      class hash<my_list<T, Allocator> >{
      public :
      size_t operator()(const my_list<T, Allocator> &x ) const{
          return ...;
      }
  };
}
Run Code Online (Sandbox Code Playgroud)

但我不能写简单的部分特化,因为它被C++ ISO禁止:

ISO/IEC 14882第三版2011-09-01

17.6.4.2.1命名空间std [namespace.std]

2如果C++程序声明了标准库类或类模板的任何成员类模板的显式或部分特化,则它的行为是未定义的.

我能做什么?

Rei*_*ica 14

您引用的段落不适用.您正在专门化一个类模板(std::hash),而不是标准库类或类模板成员类模板. std::hash不是任何类或类模板的成员.

对于您的情况,同一部分的第1段适用,并且当涉及至少一个用户定义的类型时允许专门化(强调我的):

如果C++程序向命名空间std或命名空间std中的命名空间添加声明或定义,则它是未定义的,除非另有说明.只有当声明取决于用户定义的类型 并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std.

  • @ user3098730`std :: swap`是一个*function*模板,而不是*class*模板.功能模板根本不是部分专用的; 这符合语言规则,与`std`无关. (5认同)
  • 我记得C++用户不能为":: std :: swap(T <A,B>&,T <A,B>&)"定义部分特化.他应该在命名空间中使用类"template <class A,class B> class T;"定义新的交换函数.我认为这是同样的情况. (2认同)