简体   繁体   English

将模板类专门化为结构

[英]Specializing a template class as a struct

I was just over specializing std::hash for a user-defined type using: 我刚刚使用以下方法专门为用户定义的类型专门化std::hash

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

When VC10 greeted me with the warning: 当VC10向我发出警告时:

warning C4099: 'std::hash<_Kty>': type name first seen using 'class' now seen using 'struct' 警告C4099:'std :: hash <_Kty>':使用'struct'时首先看到使用'class'看到的类型名称

and I found out that its standard library declares std::hash as class , whereas the standard (or the latest free draft I have) declares it as struct . 我发现它的标准库将std::hash声明为class ,而标准(或我最新的自由草案)将其声明为struct

Well, of course I know that a struct isn't any different from a class (except for the different default access and inheritance types). 好吧,当然我知道结构与类没有任何不同(除了不同的默认访问和继承类型)。 But my questions are: 但我的问题是:

  1. Does VC10 violate the standard here or is it free to exchange struct s for class s in any standard library components (as long as the required access types for members stay consistent, of course)? VC10是否违反了此标准,或者是否可以在任何标准库组件中为class s交换struct (当然,只要成员所需的访问类型保持一致)?
  2. Is it legal to specialize a template class as a struct and vice versa or does this bring problems with name resolution and the like (at least VC10 thinks it's worth a warning). 将模板类专门化为结构是否合法,反之亦然,或者这会带来名称解析等问题(至少VC10认为值得警告)。

First off, here is the answer to 2. taken from 14.5.1 [temp.class] paragraph 4: 首先,这是从14.5.1 [temp.class]第4段中得到的答案:

In a redeclaration, partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration. 在重新声明,部分特化,显式特化或类模板的显式实例化中,类 - 密钥应与原始类模板声明一致。

However, struct and class are referring to the same class-key according to 7.1.6.3 [dcl.type.elab] paragraph 3 last sentence: 但是,根据7.1.6.3 [dcl.type.elab]第3段最后一句, structclass引用相同的类 - 键:

The class-key or enum keyword present in the elaborated-type-specifier shall agree in kind with the declaration to which the name in the elaborated-type-specifier refers. 精细类型说明符中存在的class-key或enum关键字应与精心设计类型说明符中的名称所引用的声明一致。 [...] Thus, in any elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration, the union class-key shall be used to refer to a union, and either the class or struct class-key shall be used to refer to a class declared using the class or struct class-key. [...]因此,在任何详细类型说明符中,enum关键字应用于引用枚举,union class-key应用于引用union,以及类或struct class-key应该用于引用使用class或struct class-key声明的类。

Trying g++, clang, and EDG all agree that it is possible to specialize a template declared as struct as a class . 尝试g ++,clang和EDG都同意可以将声明为struct的模板专门化为class However, clang warns about having changed from struct to class or vice versa. 然而,clang警告说从struct改为class ,反之亦然。 Based on this, the standard library is free to choose whatever keyword it sees fit for the definition. 基于此,标准库可以自由选择它认为适合定义的任何关键字。 Obviously, if the compiler rejects the code as a result something is seriously broken but I'd think it is the compiler rather than the library which is at error in this case. 显然,如果编译器拒绝代码,结果会严重破坏,但我认为这是编译器而不是在这种情况下出错的库。

For 1: I am not sure, but I believe it is a bug. 1:我不确定,但我相信这是一个错误。

For 2: Don't worry, it shouldn't result in any weird behavior. 对于2:不要担心,它不应该导致任何奇怪的行为。 Just be careful with the scopes of functions that you define. 请注意您定义的函数范围。 As for the warning, it is actually pretty general (ie not especially made for templates), so I wouldn't care about it much. 至于警告, 它实际上非常普遍 (即不是特别针对模板),所以我不会太在意它。

Edit: See also the answer to this question, which basically says that it doesn't make any difference in the standard, but some compilers may behave strangely. 编辑:另请参阅这个问题的答案,它基本上说它在标准上没有任何区别,但是有些编译器可能表现得很奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM