继承嵌套模板类的专业化 [英] Specialization of inherited nested template class

查看:107
本文介绍了继承嵌套模板类的专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下源代码来自:
了解继承嵌套类模板的部分专门化

#include <type_traits>
struct Base
{
    template<class U, class _ = void> struct Inner: std::true_type {};
    template<class _> struct Inner<char, _>: std::false_type {};
};
struct Derived : Base
{
};

template<class _> struct Derived::Inner<int, _>: std::false_type {};

我有一个关于专门化继承类的问题,所以我google了,找出上面的问题。上面的问题中的源代码编译w / o gcc / clang中的任何问题,但是msvc拒绝编译它,发出C2427(参见 https://msdn.microsoft.com/en-us/library/10het5hx.aspx )。

I had an issue about specializing inherited class, so I googled, and find out the question above. The source code in the question above compiled w/o any problem in gcc/clang, but msvc refuses to compile it, issuing C2427 (see https://msdn.microsoft.com/en-us/library/10het5hx.aspx).

上述情况(专门化非模板类的嵌套模板类)与在 https://msdn.microsoft.com/en-us/library/10het5hx.aspx (定义模板类的嵌套非模板类),我想。

Situation of the above (specialize the nested template class of a non-template class) is quite different from the situation described in https://msdn.microsoft.com/en-us/library/10het5hx.aspx (define the nested non-template class of a template class), I think.

msvc和gcc / clang中的哪一个是错误的?

Which one of msvc vs. gcc/clang is wrong? Or just the standard is so unclear to specify this behavior?

我希望msvc是错误的...

I hope msvc is wrong...

推荐答案

Clang和GCC是错误的,MSVC和EDG拒绝部分专门化定义是正确的。

Clang and GCC are wrong, and MSVC and EDG are right to reject that partial specialization definition.

模板,并且类模板定义根据类定义(在语法术语中,类指定符)来语法构造。在这样的定义中, Derived :: Inner< int,_> 是一个类头名,其中 :: 是一个 nested-name-specifier

A partial specialization is itself a template, and a class template definition is syntactically constructed in terms of a class definition (in grammar terms, a class-specifier). Within such a definition, Derived::Inner<int, _> is a class-head-name, with Derived:: being a nested-name-specifier.

[9p11]在标准中说:

[9p11] in the Standard says:


class-head-name 包含 nested-name-specifier
class-specifier 将引用先前声明的类
直接在 nested-name-specifier
引用的类或命名空间中,或在
命名空间的内联命名空间集(7.3.1)的元素中(即,不仅仅是由
使用声明继承或引入),并且 class-specifier 将出现在
命名空间中,宣言。 [...]

If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set (7.3.1) of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration. [...]

所以,你必须使用 Base :: Inner< int,_>

如注释中所述,上面的引用适用于类模板显式专门化定义

As noted in the comments, the quote above applies to class template explicit specialization definitions as well (their grammar production also ends up using class-head-name).

请注意,上面的引用是类模板(或显式特化)定义,例如

Note that the quote above refers to class template (or explicit specialization) definitions, not declarations such as

template<class _> struct Derived::Inner<int, _>;

在语法上, struct Derived :: Inner< int,_> 中有一个 elaborated-type-specifier ,上述段落不适用。因此,标准的措辞在技术上允许这样的声明。

Syntactically, struct Derived::Inner<int, _> in there is an elaborated-type-specifier, to which the paragraph above doesn't apply. So, the Standard wording technically allows such declarations.

这似乎不是一个疏忽:上面的措辞是由 DR284 ,其中包含以下注释:

This doesn't seem to be an oversight: the wording above was introduced by the resolution of DR284, which includes the comment:


情绪是这应该是类定义,
,而不是详细的类型说明符一般(这是
引用,而不是声明) 。 [...]

The sentiment was that this should be required on class definitions, but not on elaborated type specifiers in general (which are references, not declarations). [...]

建议的解决方案包括 elaborated-type-specifiers 最后的措辞。

The proposed resolution included elaborated-type-specifiers, but those were removed from the final wording.

然而,MSVC和EDG都不接受这样的声明(坦率地说,我会发现它很困惑,如果他们)。 DR中的注释似乎表明意图是仅允许不是声明的 elaborated-type-specifiers ,但它看起来像没有反映在措辞中(一个标准错误,我想)。

However, neither MSVC nor EDG accept such declarations (and frankly I'd find it confusing if they did). The comment in the DR seems to indicate that the intent was to allow only elaborated-type-specifiers that are not also declarations, but it looks like this wasn't reflected in the wording (a Standard bug, I think).

这篇关于继承嵌套模板类的专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆