Позвольте мне рассмотреть шаблонный класс, который является производным от базового шаблонного класса. Базовый класс содержит член шаблона. В этом случае обычно члены базового класса могут быть доступны из производного класса с помощью указателя this
. Однако, похоже, что это не тот случай, когда базовый элемент сам является функцией шаблона.
Рассмотрим следующий код
#include <iostream>
template <class T>
struct base {
T x;
base() { x = 10; }
template <unsigned int N>
void increment() { x += N; }
};
template <class T>
struct deriv : public base<T> {
using base<T>::base;
void p()
{
using namespace std;
cout << this->x << endl;
base<int>::increment<1>();
// The following statement causes the compile error:
// expected primary-expression before ‘)’ token
// this->increment<1>();
// Also the following statement gives error
// base<T>::increment<1>();
cout << this->x << endl;
}
};
int main()
{
using namespace std;
base<int> A;
cout << A.x << endl;
A.increment<1>();
cout << A.x << endl;
deriv<int> B;
B.p();
return 0;
}
В подпрограмме main
элемент шаблона increment
вызывается из переменной типа base
. Это работает без проблем.
С другой стороны, функция-член p()
класса deriv
пытается получить доступ к шаблонной функции increment
, унаследованной от базы. Используя указатель this
как в закомментированной строке выше
this->increment<1>();
выдает ошибку компиляции
expected primary-expression before ‘)’ token
Попробовав некоторое время, я обнаружил, что, как и в приведенном выше коде, возможно получить доступ к функции increment
через оператор области действия
base<int>::increment<1>();
Это, однако, явно создает base
с T=int
. Если я хочу вызвать increment
член из унаследованного base<T>
, с общим T
классом как
base<T>::increment<1>();
Я получаю ту же ошибку, что и выше.
Я использую gcc 8.1.1
Вопрос в том, почему при использовании указателя this
компилятор не может разрешить унаследованную функцию-член increment
? Как я могу получить экземпляр унаследованной функции шаблона increment
из унаследованного класса base
?
Редактировать: я добавил еще один случай, когда он не компилируется, лучше уточните вопрос.
Редактировать: небольшая коррекция в программе, тот же вопрос.