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