C++模板成员专门化 - 这是编译器限制吗?

Lou*_*ong 4 c++ templates

有可能做这种专业化吗?
如果是这样,怎么样?

有问题的专业标记//这个专业化不会编译 我已经使用过VS2008,VS2010,gcc 4.4.3并且都不能编译它.

我知道我可以通过重载func来避免这种情况,但我想知道是否有办法用模板专业化来做到这一点.(尽管可能是不切实际的/不可取的)

#include<iostream>
#include<string>

using namespace std;

template <typename ALPHA>
class klass{
    public:
        template <typename BETA>
        void func(BETA B);
};

template <typename ALPHA> template <typename BETA>
void klass<ALPHA>::func(BETA B){
    cout << "I AM A BETA FUNC: " << B <<endl;
}

//THIS SPECIALIZATION WILL NOT COMPILE
template <typename ALPHA> template <>
void klass<ALPHA>::func(string B){
    cout << "I AM A SPECIAL BETA FUNC: " << B <<endl;
}

int main(){
    klass<string> k;
    k.func(1);
    k.func("hello");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Tyl*_*nry 6

只是使string的版本func,与模板版本超载常规非模板成员函数:

#include<iostream>
#include<string>

using namespace std;

template <typename ALPHA>
class klass{
    public:
        template <typename BETA>
        void func(BETA B);
        void func(string b);
};

template <typename ALPHA> template <typename BETA>
void klass<ALPHA>::func(BETA B){
    cout << "I AM A BETA FUNC: " << B <<endl;
}

template <typename ALPHA>
void klass<ALPHA>::func(string B){
    cout << "I AM A SPECIAL BETA FUNC: " << B <<endl;
}

int main(){
    klass<string> k;
    k.func(1);
    k.func("hello");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

除了编译之外,还有另一个好处,即您将获得更直观的行为.请参阅"为什么不专门化功能模板?" 来自GOTW.

编辑:要直接回答您的原始问题,这不是编译器限制,它是C++标准不允许的.

C++标准,14.7.3/18(部分)说:

在类模板成员或出现在命名空间作用域中的成员模板的显式特化声明中,成员模板及其某些封闭类模板可能保持非专业化,除非声明不应明确专门化类成员模板封闭类模板也没有明确专门化.

这意味着既然klass是模板,你就不能专业化klass::func而不专业化klass.


AnT*_*AnT 3

回答您在标题中提出的问题:不,这不是编译器限制。这是语言限制。在 C++ 中,为了显式特化嵌套模板(可以是类模板或成员函数模板),您还必须显式特化封闭模板。

您试图显式地专门化嵌套模板而不专门化封闭模板。这不会编译。

当涉及到成员函数模板时,当模板参数与某些函数参数关联时(如您的情况),您通常可以用重载替换显式专业化,如泰勒的答案中所建议的。在其他情况下,您必须使用不同的解决方法。