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

C++ C++;模板成员专门化-这是编译器限制吗?,c++,templates,C++,Templates,有可能进行这种专门化吗? 如果是,怎么做 正在讨论的专门化已标记//此专门化将不会编译 我使用过VS2008、VS2010、GCC4.4.3,但这两个版本都不能编译 我知道我可以通过重载func来避免这种情况,但我想知道是否有一种方法可以通过模板专门化来做到这一点。(尽管可能不切实际/不可取) #包括 #包括 使用名称空间std; 模板 克拉斯班{ 公众: 模板 void func(βB); }; 模板 void klass::func(BETA B){ cout只需将string版本的func

有可能进行这种专门化吗?
如果是,怎么做

正在讨论的专门化已标记//此专门化将不会编译 我使用过VS2008、VS2010、GCC4.4.3,但这两个版本都不能编译

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

#包括
#包括
使用名称空间std;
模板
克拉斯班{
公众:
模板
void func(βB);
};
模板
void klass::func(BETA B){

cout只需将
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;
}
#包括
#包括
使用名称空间std;
模板
克拉斯班{
公众:
模板
void func(βB);
void func(字符串b);
};
模板
克劳斯

<> > >编辑:直接回答你原来的问题,不,这不是编译器限制,是C++标准不允许的东西。

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

以明确的专业化 类成员的声明 模板或 出现在命名空间范围中,成员 模板及其一些封装 类模板可能会保留 非专业化,除了 声明不应明确 如果需要,则专门化类成员模板 它的封闭类模板不可用 也明确专门化。


这意味着,既然<代码> KLAS< /COD>是模板,就不能专门化<代码> KLAS::FUNC,也不需要专门的代码> KLAS< /COL>

< P>来回答标题中的问题:不,这不是编译器限制。这是语言限制。C++中,为了明确地专门化嵌套模板。(可以是类模板或成员函数模板)还必须显式地专门化封闭模板

您正在尝试显式专门化嵌套模板,而不专门化封闭模板。这将无法编译


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

如果您将专门化更改为
void klass::func(string B);
?这样,它是函数模板的完全专门化(在模板类中)。至少,我想,我现在手头没有编译器。使用g++时,示例编译器没有错误。这不起作用,k.func(“hello”);将调用模板函数而不是重载函数。因为
“hello”
是一个
常量字符*
,而不是
字符串
。请为
常量字符*
添加另一个重载,或调用为
k.func(字符串(“hello”)
#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;
}