Явная специализация шаблона производного класса - PullRequest
0 голосов
/ 13 июля 2020

У меня есть шаблон класса, который реализует ряд функций. Я также хочу иметь возможность добавить специализированную версию этого класса, в которой есть только несколько функций, которые переопределяют функции базового, когда объявлен конкретный тип c. Я знаю, что могу добиться этого с помощью шаблона класса и его явной специализации. Однако я также хочу:

  • Иметь уникальные имена явных специализаций, аналогично тому, как однозначно именуются базовый и производный классы.
  • Вызвать функции Base из экземпляра Derived, либо внутри функции Derived, либо явно, как показано ниже, с obj1.Foo

Это (упрощенный) пример кода, который я пытаюсь заставить работать:

В myClasses.h

template<typename T>
class Base
{
  public: 
    void Foo (T& input);
    virtual void Bar (T& input);
}

template<>
class Derived : public Base<int>
{
  public: 
    void Bar (int& input) override;
}

В myClasses. cpp

template<typename T>
Base::Foo(T& input) { // Do something generic }

template<typename T>
Base::Bar(T& input) { // Do something generic }

template<>
Derived::Bar(int& input) { // Do something int-dependent }

В основном. cpp

int main()
{
  Base<int> obj1 = new Derived();
  obj1.Foo(input);                  // Runs Base::Foo
  obj1.Bar(input);                  // Runs Derived::Bar
}

Однако этот код не работает с explicit specialization of non-template Derived ошибка, среди прочего. Я прочитал много потоков StackOverflow, чтобы зайти так далеко, но я не нашел ни одного, что помогло бы мне сделать эту компиляцию. Итак, мои вопросы:

  1. Возможно ли таким образом объединение шаблонов классов с наследованием классов?
  2. Почему компилятор помечает производный класс как не шаблон, несмотря на то, что я явно использовал это ключевое слово ?
  3. Какой правильный синтаксис заставит этот код работать? (при условии, что то, что я пытаюсь сделать, возможно)

EDIT: Следуя предложению HTNW, я могу превратить Derived в обычный класс, удалив template<> префикс. Это позволит компилировать все до obj1.Foo(input). Кажется, что созданный экземпляр класса Derived не может найти или получить доступ к базовой функции Foo.

1 Ответ

0 голосов
/ 15 июля 2020

Спасибо ravnsgaard и HTNW за полезные предложения, которые помогли мне найти решение. Ключ состоял в том, чтобы удалить ключевое слово template<> из класса Derived (потому что я хотел, чтобы это был класс, а не шаблон класса) и объявление Base<int> в конце исходного файла. Итак, рабочий код выглядит так:

В myClasses.h

template<typename T>
class Base
{
  public: 
    void Foo (T& input);
    virtual void Bar (T& input);
}

class Derived : public Base<int>
{
  public: 
    void Bar (int& input) override;
}

в myClasses. cpp

template<typename T>
Base::Foo(T& input) { // Do something generic }

template<typename T>
Base::Bar(T& input) { // Do something generic }

Derived::Bar(int& input) { // Do something int-dependent }

template class Base<int>; // VERY IMPORTANT.

В основном. cpp

int main()
{
  Base<int> &&obj1 = Derived();
  obj1.Foo(input);                  // Runs Base::Foo
  obj1.Bar(input);                  // Runs Derived::Bar
}

В частности, без объявления template class Base<int>; в конце myClasses. cpp вызов obj1.Foo завершится ошибкой с сообщением, что Derived не имеет такой функции.

...