C ++: частичная специализация шаблонов - PullRequest
0 голосов
/ 10 февраля 2020

Я заметил, что всякий раз, когда класс шаблона является специализированным (частично / полностью), все функции-члены должны быть явно определены, в противном случае возникает ошибка. Вот пример ниже

#include <iostream>

template<typename T, typename U> //Primary
struct test
{
   void f() { std::cout << "\nPrimary"; }
   void g() { std::cout << "Called g()\n";}
};

template <typename T> //Specialization
struct test<T, int*>
{
   void f() { std::cout << "\nPartial Specialization"; }
};


template<> //Full specialization
struct test<int*, int*>
{
   void f() { std::cout << "\nFull Specialization\n"; }
};

int main()
{
    test<int, double> t1;
    t1.f();
    t1.g();

    test<double, int*> t2;
    t2.f();
    t2.g();

    test<int*, int*> t3;
    t3.f();
    t3.g();
}

Здесь t2.g() и t3.g() дает ошибку времени компиляции, поскольку они не определены явно. Если для каждой специализации функции-члены должны быть определены снова. В чем преимущество частичной / полной специализации?

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

Я думаю, что вы неправильно поняли специализацию классов. Классовая специализация не inheritance. Специализированный класс отличается от исходного. Ничего не поделено между двумя. И, следовательно, в специализированных методах g() не существует.

Если вы ищете способ просто изменить методы, вам следует вместо этого обратиться к специализациям методов.

0 голосов
/ 10 февраля 2020

Я думаю, что главной целью для специализации является определение «исключений», если вы хотите обрабатывать некоторые типы данных по-разному.

Рассматривая частичную специализацию, обратите внимание на следующее:

// NOT specialized
template <typename T>
struct test <T, T>
{
   ...
};

// partially specialized
template <typename T>
struct test <T*, T*>
{
  ...
}; 

Последний пример уже частично специализирован, потому что вы указываете компилятору ожидать любой тип указателя. И это может быть полезно, конечно, потому что вы можете захотеть обрабатывать типы указателей, немного отличающиеся от типов без указателей (например, проверка на NULL)

Я рекомендую прочитать эту статью

...