是否可以进行这种专业化?
如果是这样,怎么样?
有问题的专业标记为 //此专业化不会编译 我使用过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;
}
答案 0 :(得分: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;
}
除了编译之外,还有另一个好处,即您将获得更直观的行为。请参阅"Why Not Specialize Function Templates?" from GOTW。
编辑:要直接回答原始问题,这不是编译器限制,它是C ++标准不允许的内容。
C ++标准,14.7.3 / 18(部分)说:
明确的专业化 一个班级成员的声明 模板或成员模板 出现在命名空间作用域中的成员 模板和它的一些封闭 类模板可能会保留 非专业,除了 声明不得明确 如果要专门化一个类成员模板 它的封闭类模板不是 也明确专业。
这意味着由于klass
是一个模板,因此如果不专门设置klass::func
,则无法专门化klass
。
答案 1 :(得分:3)
要回答标题中提出的问题:不,这不是编译器限制。这是一种语言限制。在C ++中,为了明确地专门化嵌套模板(是类模板或成员函数模板),您还必须明确地专门化封闭模板。
您正在尝试显式专门化嵌套模板而不专门化封闭模板。这不会编译。
当涉及到成员函数模板时,当模板参数与某个函数参数相关联时(如在您的情况下),您通常可以使用重载替换显式特化,如Tyler的答案中所建议的那样。在其他情况下,您必须使用不同的解决方法。