子命名空间中的类模板特化

时间:2018-01-13 11:55:39

标签: c++ templates namespaces template-specialization

几乎没有类似的问题,但是关于不同的命名空间中的专门化类。

这里我有一段代码,它在MSVC上编译,但不能在gcc上编译,clang:

template<typename T>
struct type_of {};

class ClassA {};

template<>
struct type_of<ClassA> {
    using type = ClassA;
};

namespace space {

    class ClassBInNamespace {};

    template<typename T>
    class TemplateClassCInNamespace {};

    template<>
    struct type_of<ClassBInNamespace> {
        using type = ClassBInNamespace;
    };

    template<typename T>
    struct type_of<TemplateClassCInNamespace<T>> {
        using type = /*does not compile with MSVC without namespace: space::*/TemplateClassCInNamespace<T>;
    };
}

int main(int, char*[]) {

    type_of<ClassA>::type classA;
    type_of<space::ClassBInNamespace>::type classB;
    type_of<space::TemplateClassCInNamespace<int>>::type classC;
}

所以MSVC允许在封闭命名空间(全局)的子命名空间中使用type_of特化,但是当类是模板时有一个奇怪的问题:

  

错误C2061:语法错误:标识符'TemplateClassCInNamespace'

     

main.cpp(25):错误C2238:';'之前的意外令牌

关于此的标准说: 应在包含专用模板的命名空间中声明显式特化。其声明者id未限定的显式特化应在模板的最近的封闭命名空间中声明,或者,如果命名空间是内联(7.3.1),则从其封闭的命名空间集中声明任何命名空间。这样的声明也可以是一个定义。如果声明不是定义,则可以稍后定义专业化(7.3.1.2)。

我理解第一句话 - 我可以在模板的'parent-namespace'中使用专门的模板(与示例相反)。 但我完全不明白第二部分..

应该允许专门使用子命名空间吗? 编译 type_of&lt;的特殊化是不是MSVC错误的? ClassBInNamespace&gt; 或不编译 type_of&lt; TemplateClassCInNamespace&LT; T> &gt; 在子命名空间?

0 个答案:

没有答案