Страницы

Поиск по вопросам

четверг, 19 марта 2020 г.

Уточнение шаблона функции

#cpp #шаблоны_с++


Ясного неба!

Читаю учебник по с++. Там есть пример уточнения шаблона класса:

template class 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: template void 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(){}; template void 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;};

Комментариев нет:

Отправить комментарий