繁体   English   中英

继承的嵌套模板类的专业化

[英]Specialization of inherited nested template class

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

#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搜索了一下,找出了上面的问题。 上面问题中的源代码编译了gcc / clang中的任何问题,但msvc拒绝编译它,发出C2427(请参阅https://msdn.microsoft.com/zh-cn/library/10het5hx.aspx )。

以上情况(专门用于非模板类的嵌套模板类)与https://msdn.microsoft.com/zh-cn/library/10het5hx.aspx中描述的情况有很大不同(定义嵌套的非模板类,我认为是模板类)。

msvc与gcc / clang中的哪一个是错误的? 还是只是标准尚不清楚以指定这种行为?

我希望msvc是错误的...

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

部分专业化本身就是模板,而类模板定义是根据类定义(在语法上为class-specifier )语法构建的。 在这样的定义中, Derived::Inner<int, _>是一个类头名称 ,而Derived::是一个嵌套名称说明符

标准中的[9p11]说:

如果一个类名包含一个嵌套名称说明符 ,则该类说明符应引用先前在该嵌套名称说明符所引用的类或名称空间中或在其元素中直接声明的类。该名称空间的内联名称空间集(7.3.1)(即,不仅由using-declaration继承或引入),并且class-specifier应出现在包含先前声明的名称空间中。 [...]

因此,您必须使用Base::Inner<int, _>


如评论中所述,以上引用也适用于类模板显式专业化定义(它们的语法生成也最终使用class-head-name结束 )。


以下内容不适用于您的示例,但我发现值得一提。

请注意,上面的引用引用的是类模板(或显式专业化)定义,而不是诸如

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

从语法上讲, struct Derived::Inner<int, _>中有一个详尽的类型说明符 ,以上段落不适用于该说明符 因此,标准措词在技术上允许此类声明。

这似乎不是疏忽:上面的措辞是由DR284决议引入的,其中包括评论:

人们的观点是,这应该在类定义上是必需的,但一般而言在详细的类型说明符(不是引用,而是声明)上都不需要。 [...]

拟议的决议包括详细的类型说明符 ,但这些内容已从最终措辞中删除。

但是,MSVC和EDG都不接受此类声明(坦率地说,如果这样做,我会感到困惑)。 DR中的注释似乎表明,其目的是仅允许既不是声明也不是声明的详尽的类型说明符 ,但这似乎没有体现在措辞上(我认为是标准错误)。

暂无
暂无

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

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