наследование c ++ от специализированного шаблонного класса

template<typename T1, typename T2, typename T3>
class A: public A<T1, T2, void> {
public:
T1 a;
T2 b;
T3 c;

void set() { a = aa; } // Cannot find variable `aa' here!
};

template<typename T1, typename T2>
class A<T1, T2, void> {
public:
T1 aa;
T2 bb;
};

Как и выше, у меня есть шаблон класса Aи его частичная специализированная форма A', Так может ли А наследовать от А ‘? По словам g ++, кажется, все в порядке. Однако когда я попытался получить доступ к членам в A ‘, g ++ начал жаловаться: не удалось найти этот символ. Кто-нибудь знает почему?

1

Решение

Насколько я помню, вы должны добавить aa к производному классу с помощью ‘using’. Добавьте следующее (я не помню точный синтаксис, так что извините меня за проблемы с компиляцией) к вашему универсальному шаблону:

using A<T1, T2, void>::aa;

РЕДАКТИРОВАТЬ: Как Mehrdad отметил, что это -> аа также должно работать.

1

Другие решения

Правила поиска имени в шаблонах C ++ могут показаться немного не интуитивными. Когда компилятор сначала анализирует определение шаблона, он разрешает все имена, которые не являются зависимый от шаблона аргумент. Когда дело доходит до создания экземпляра шаблона, он разрешает все остальное.

Если вы посмотрите на определение класс А только нет очевидной зависимости символа аа на аргументы типа T1, T2 или T3. Таким образом, компилятор пытается разрешить имя, но не может, так как это имя не определено в этой среде.

Итак, чтобы убедить компилятор сделать то, что вы хотели, вы должны использовать следующие приемы:

  • Самый простой, наверное, this-> аа. поскольку этот имеет зависимый от аргумента шаблона суперкласс, его члены можно искать только во время создания шаблона, так что все в порядке.

  • Квалифицировать участника с помощью суперкласса, то есть использовать <T1, T2, пустота>:: аа. Это делает зависимость действительно очевидной. Вы также можете использовать с помощью директива, так что не нужно вводить это каждый раз.

0

По вопросам рекламы [email protected]