将模板类专门化为结构

时间:2012-02-20 23:11:55

标签: c++ class struct template-specialization

我刚刚使用以下方法专门为std::hash提供了用户定义的类型:

template<>
struct hash<...> {...};

当VC10向我发出警告时:

  

警告C4099:'std :: hash&lt; _Kty&gt;':首先看到使用'class'的类型名称   现在看到使用'struct'

我发现其标准库将std::hash声明为class,而标准(或我拥有的最新免费草稿)将其声明为struct

当然,我知道结构与类没有任何不同(除了不同的默认访问和继承类型)。但我的问题是:

  1. VC10是否违反此标准,或者是否可以在任何标准库组件中struct更换class s(只要成员所需的访问类型保持一致)?
  2. 将模板类专门化为结构是否合法,反之亦然,或者这会带来名称解析等问题(至少VC10认为值得警告)。

2 个答案:

答案 0 :(得分:8)

首先,这是从14.5.1 [temp.class]第4段获取的答案:

  

在类模板的重新声明,部分特化,显式特化或显式实例化中,类 - 密钥应与原始类模板声明一致。

但是,根据7.1.6.3 [dcl.type.elab]第3段最后一句,structclass指的是同一个类密钥:

  

elaborated-type-specifier中存在的class-key或enum关键字应与详细类型说明符中的名称所引用的声明一致。 [...]因此,在任何详细类型说明符中,enum关键字应用于引用枚举,union class-key应用于引用union,以及类或struct class-key应该用于引用使用class或struct class-key声明的类。

尝试g ++,clang和EDG都同意可以将声明为struct的模板专门化为class。但是,clang警告说已从struct更改为class,反之亦然。基于此,标准库可以自由选择它认为适合定义的任何关键字。显然,如果编译器拒绝代码,结果会严重破坏,但我认为这是编译器而不是在这种情况下出错的库。

答案 1 :(得分:0)

1:我不确定,但我相信这是一个错误。

For 2:别担心,它不应该导致任何奇怪的行为。请注意您定义的函数范围。至于警告,it is actually pretty general(即不是特别针对模板制作的),所以我不会太在意它。

编辑:另请参阅this问题的答案,该问题基本上表明它在标准方面没有任何区别,但有些编译器可能表现得很奇怪。