Есть ли способ вызвать реализацию универсального шаблона класса из его специализации? - PullRequest
1 голос
/ 01 октября 2019

У меня есть шаблон класса

template<typename T>
class D : public B {...}

, где B - чистый виртуальный интерфейс, реализованный в классе D. Однако для одного типа T0 реализация имеет дополнительные данные и дополнительную функцию-член, работающую с этими данными. ,Поэтому я должен специализировать класс D для этого случая:

template<>
class D<T0> : public B {...}

В то же время реализация всех других методов в этой специализации точно такая же, как в общем случае, и я не хочускопировать и вставить его. Вопрос в том, как вызвать универсальную реализацию в классе D из класса D<T0>, если это вообще возможно.

PS. Конечно, есть решение с промежуточным производным классом C, как предложено @MaxLanghof и @Klaus. Однако в этом решении можно создать экземпляр класса C<T0>, который я не хочу. Это решение является последним средством, которое я буду использовать, если не существует другого решения. Может быть, в C ++ 11/14 есть какие-то современные конструкции, которые могут помочь в таких случаях?

Ответы [ 2 ]

5 голосов
/ 01 октября 2019

Добавьте еще один слой.

template<typename T>
class C : public B { /* all the non-specialized implementation of D */ };
// (possibly hide this in some implementation detail namespace)

// Use the non-specialized implementation by default
template<typename T>
class D : public C {};

// Add more functionality in the specialized case
template<>
class D<T0> : public C { /* your additional functionality */ };
4 голосов
/ 01 октября 2019

В то же время реализация всех других методов в этой специализации точно такая же, как и в общем случае.

Таким образом, вы должны разделить общий код на общую базуКласс и производные от этого нового промежуточного класса для общего и специализированного шаблона. Нет смысла иметь полное дублирование кода для специализации шаблона.

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

РЕДАКТИРОВАТЬ: Относительно комментариев: Как защитить, чтобы создать экземпляр объекта промежуточного класса:

У вас есть ключевое слово protected в C ++, что позволяет защитить доступ к конструктору.

Пример:

class B{};
class T0;


template<typename T>
class C : public B /* all the non-specialized implementation of D */
{
    protected: C() {}
};


// Use the non-specialized implementation by default
template<typename T>
class D : public C<T> {};

// Add more functionality in the specialized case
template<>
class D<T0> : public C<T0> { /* your additional functionality */ };

int main()
{
    D<int> dint;
    D<T0>  dt0;

    C<int> Cint; // fails
    C<T0> Ct0;   // fails
}
...