【问题标题】:Why the difference in syntax between explicit and partial specialization?为什么显式和部分特化之间的语法差异?
【发布时间】:2012-01-11 00:57:39
【问题描述】:

例子:

template <typename T, typename U>
struct A {
    void Print() {}
};

template <>
void A<int, float>::Print() {} // Okay                   

template <typename T>
void A<T, char>::Print() {} // Will produce error

问题:

我知道你必须在上面的代码中定义类模板部分特化才能工作,我也从标准中知道The members of the class template partial specialization are unrelated to the members of the primary template (§ 14.5.5.3)。但是,为什么显式特化和偏特化在语法上有区别呢?

【问题讨论】:

    标签: c++ templates template-specialization


    【解决方案1】:

    您不能部分专门化函数模板,只能完全专门化。

    第一个实例利用了类模板的成员函数本身就是函数模板这一事实,因此限制适用于它们。

    当您部分特化类模板时,您将拥有一个全新的类模板,您必须重新定义它。

    【讨论】:

    • “类模板的函数本身就是函数模板” - 在类之外定义的类模板的成员函数定义为函数模板。但它们真的是等价的吗?
    • @Jesse 不,它们不相等。没有术语来描述类模板的成员函数的“模板性”。它们不是函数模板。有些人称他们为“temploid”。对应的问题是open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1253
    • @JohannesSchaub-litb:感谢您的澄清。希望尽快添加活动问题的描述。
    【解决方案2】:
    template <typename T>
    void A<T, char>::Print() {} // Will produce error
    

    你是:

    1. 重新定义一个函数(它在声明void Print() {}时已经定义了,你看到有{}。
    2. 带有与声明不匹配的模板参数列表:template &lt;typename T, typename U&gt; void Print()

    事实上,即使你在声明的时候没有定义函数,你仍然会报错,因为你的声明和定义不匹配,编译器将无法找到原始模板的定义,或者专用模板的声明。

    与结构相关的函数的专用模板函数也必须具有专用结构,此代码有效:

    template <typename T, typename U>
    struct A {
        void Print() {}
    };
    
    template <>
    void A<int, float>::Print() {} // Okay                   
    
    
    template <typename T>
    struct A<T,char>
    {
        void Print();
    };
    
    template <typename T>
    void A<T,char>::Print() {}
    

    因为模板函数已经在它的模板结构中声明了。

    【讨论】:

    • 我不确定这个解释。这是标准的引用:The definitions of members of the primary template are never used as definitions for members of a class template partial specialization.
    • 我没有看到引用和解释之间有任何对立,你有什么意义?
    • 您提到了re-defining,但是类模板特化是与主模板无关的不同模板,因此不涉及重新定义。当编译器看到A&lt;T, char&gt; 时,它需要一个专门的定义。您是否尝试编译它并查看错误?即使您在声明函数时没有定义函数,也会发生相同的错误(尽管我意识到我不应该相信错误总是告诉我的。)
    猜你喜欢
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 2011-07-27
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    相关资源
    最近更新 更多