Ясного неба!
Читаю учебник по с++. Там есть пример уточнения шаблона класса:
template<typename T> class MyCout
{
private:
T data;
public:
MyCout(T a): data(a) {};
void display() {cout << data << endl;};
};
template<> class MyCout<string>
{
private:
string data;
public:
MyCout(string a): data(a){};
void display() {cout << data.c_str() << endl;};
};
Я решил поэкспериментировать, и немного укоротить код, сделав шаблон не целого класса, а только функции:
class NewCout
{
public:
NewCout(){};
template<typename T> void display(T a){cout << a << endl;};
template<> void display<string>(string a){cout << a.c_str() << endl;};
};
Но компилятор выдает ошибку на строке №6: invalid explicit specialization before '>' token.
Что я делаю не так?
И еще вопрос вдогонку: как принято оформлять шаблоны?
C++ запрещает частичную специализацию методов, только шаблоны классов могут быть специализированы. См. стандарт, параграф 14.5.6. Почему именно так было сделано, обсуждается здесь (ворнинг: инглиш лэнгвидж инсайд!).
Судя по всему, автор книги не прав.
Вы можете, однако, перегрузить шаблонный метод (что не то же самое).
Ох, позор мне. Вот это работает:
class C
{
public:
template<typename T>
void f(T t);
};
template<typename T>
void C::f(T t)
{
cout << t << endl;
}
template<>
void C::f<int>(int t)
{
cout << "(int specialization) " << t << endl;
}
Разобрался. В примере над чертой не частичная, а полная специализация. Частичная специализация всё-таки запрещена, как и говорит спецификация. Пример:
class C
{
public:
template<typename T>
void f(T t);
};
template<typename T>
void C::f(T t)
{
cout << t << endl;
}
template<typename T> // ошибка: function template partial
void C::f<T*>(T* pt) // specialization ‘f<T*>’ is not allowed
{
cout << "(pointer specialization) " << *pt << endl;
}
Как вариант вынести специализации вне класса
class NewCout
{
public:
NewCout(){};
template<typename T> void display(T a){cout << a << endl;};
};
template<> void NewCout::display<string>(string a){cout << a.c_str() << endl;};
Не знаю насколько это правильное решение, как по мне вся эта шаблонная магия от лукавого. Тем более что специализация шаблона в таком тривиальном случае и не нужна
class NewCout
{
public:
NewCout(){};
template<typename T> void display(T a){cout << a << endl;};
void display(string a){cout << a << endl;};
};
template<> void display(string a){cout << a.c_str() << endl;};
Продвижение своими сайтами как стратегия роста и независимости