Просто сделайте 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;
}
В дополнение к компиляции, здесь есть еще одно преимущество:получит более интуитивное поведение.См. «Почему бы не специализировать шаблоны функций?»из GOTW .
Редактировать: Чтобы прямо ответить на ваш исходный вопрос, нет, это не ограничение компилятора, это то, что запрещено стандартом C ++.
Стандарт C ++, 14.7.3 / 18, говорит (частично):
В явном объявлении специализации для члена шаблона класса или шаблона члена, который появляется в области пространства имен, членшаблон и некоторые из его шаблонов классов могут оставаться в стороне, за исключением того, что объявление не должно явно специализировать шаблон члена класса, если его шаблоны классов также не являются явно специализированными.
Это означает, что, поскольку klass
является шаблоном, вы не можете специализировать klass::func
, не специализируя также klass
.