了解继承嵌套类模板的部分专门化 [英] Understanding partial specialization of inherited nested class templates

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

问题描述

此问题已连结至前面的Q& A ,其中提到了gcc的错误报告(据说固定在gcc 4.5.0中),并且涉及嵌套类模板的部分特化的一些特性。

This question is connected to a previous Q&A in which a bug report for gcc was mentioned (supposedly fixed in gcc 4.5.0) and concerns some peculiarities for partial specialization of nested class template.

我的设置是我有一个类 Base 和一个嵌套类模板 Inner 部分专用于 char (使用虚拟参数技巧,因为在类中不允许显式speciliztion)。

My setup is that I have a class Base with a nested class template Inner that is partially specialized for char (using the dummy parameter trick, because explicit speciliaztion is not allowed in-class).

#include <type_traits>
#include <iostream>
#include <ios>

struct Base
{
    // dummy template parameter...
    template<class U, class _ = void> struct Inner: std::true_type {};

    // ... to allow in-class partial specialization
    template<class _> struct Inner<char, _>: std::false_type {};
};

我现在定义一个 Derived 我还想要专门化 Inner ,由于一些奇怪的原因,不能在类中做(即使它仍然是部分专业化)。

I now define a Derived class for which I further want to specialize Inner, which for some odd reason cannot be done in-class (even though it is still a partial specialization).

struct Derived
:
    Base
{
    // cannot partially specialize Inner inside Derived...
    //template<class _>
    //struct Inner<int, _>: std::false_type {};
};

// ... but specializing Derived::Inner at namespace scope, also specializes it for Base::Inner
template<class _> struct Derived::Inner<int, _>: std::false_type {};

第一个问题:为什么我必须部分专业化 Derived :: Inner 在命名空间范围?

First question: why do I have to partially specialize Derived::Inner at namespace scope?

但是最奇怪的部分是,当我调用 的部分专门化 c> int ,我只对 Derived 有效,也适用于 Base p>

But the strangest part is that when I call the various partial specializations of Inner from both Base and Derived, the partial specialization for int that I only did for Derived, also applies to Base.

int main()
{
    std::cout << std::boolalpha << Base::Inner<float>::value << "\n";    
    std::cout << std::boolalpha << Derived::Inner<float>::value << "\n";    

    std::cout << std::boolalpha << Base::Inner<char>::value << "\n";    
    std::cout << std::boolalpha << Derived::Inner<char>::value << "\n";    

    std::cout << std::boolalpha << Base::Inner<int>::value << "\n";      // huh???
    std::cout << std::boolalpha << Derived::Inner<int>::value << "\n";   // OK 
}

第二个问题:为什么 Base :: Inner< int> :: value 等于 false ,即使只有 Derived: :Inner< int> 是部分专用的?

Second question: why is Base::Inner<int>::value equal to false, even though only Derived::Inner<int> was partially specialized?

在线示例使用gcc 4.8.0 。我特别寻找来自标准的引用,解释这种行为。

Online example using gcc 4.8.0. I am specifically looking for quotes from the Standard that explain this behavior.

推荐答案

部分专业化必须重命名与主要

A partial specialization must redeclare the same name as the primary template for which it provides an alternative definition.

在<$ c $范围内写 struct Inner c> Derived ,您将声明 Derived :: Inner Base :: Inner 是一个与 Derived :: Inner 不同的名称,因此声明了一个不同的类。不可能用声明 Derived :: Inner 的声明来专门化 Base :: Inner

When you write struct Inner within the scope of Derived, you are declaring Derived::Inner. Base::Inner is a distinct name from Derived::Inner and therefore declares a different class. It is not possible to specialize Base::Inner with a declaration that declares Derived::Inner.

当在命名空间范围写入 Derived :: Inner 时,name lookup会将该名称解析为 Base :: Inner - 专业化都是相同的类: Base :: Inner ,即使你将它们称为 Derived :: Inner

When you write Derived::Inner at namespace scope, name lookup resolves that name to Base::Inner - the specializations are all of the same class: Base::Inner, even if you refer to them as Derived::Inner.

从标准:


[temp.class.spec]

[temp.class.spec]

类模板的部分特化提供了模板的替代定义

A partial specialization of a class template provides an alternative definition of the template that is used instead of the primary definition when the arguments in a specialization match those given in the partial specialization.

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

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