Псевдонимы типов в шаблонных классах

202
20 сентября 2018, 20:50

Пример:

#include <utility>       // std::pair
#include "vertex.hpp"    // IVertex class 
template <typename Key>
class IEdge {
public:
    using   VertexPtr = IVertex<Key>*;
    using Endvertices = std::pair<VertexPtr, VertexPtr>;
// ...
public:
    Endvertices& endvertices() noexcept = 0;    
};
template <typename Key = int>
class Edge : public IEdge<Key> {
public:
    // interface: IEdge
    Endvertices& endvertices() noexcept override;
};

Компилятор выдает огромное количество ошибок связанных с отсутствием кейворда typename и добавление последнего не помогает.

Вопрос: как с этим бороться? Должен ли я перед каждым псевдонимом указывать базовый класс с текущим шаблонным параметром, вроде:

typename IEdge<Key>::Envertices 

Если так, то прошу объяснить, чем обусловливается такая необходимость в контексте использования шаблонов.

Answer 1

Да, в дочернем классе при обращении к типам базового класса следует обязательно указывать префикс с именем класса и typename. Дело в том, что до инстанцирования шаблона наличие в базовом шаблонном классе IEdge тех или иных компонентов еще не известно (так как они могут варьироваться в зависимости от праметра Key) и компилятор не способен определить происхождение идентификатора Endvertices.

Answer 2

У вас тут перемешались две независимые проблемы.

Во-первых, никакого отношения к отсутствию typename ошибки в этом коде не имеют. Ошибки в этом коде вызваны тем, что в ситуациях, когда базовый класс является зависимым типом, обыкновенный поиск неквалифицированных имен не будет выполнять поиск в этом базовом классе. Поэтому использованные в классе-наследнике неквалифицированные имена вроде Endvertices найдены не будут. (см., например, Ошибка в иерархии классов 2)

typename здесь ни при чем. Неудивительно, что добавление typename не помогает.

Во-вторых, если бы речь шла о полях или методах базового класса, проблему можно было бы решить либо обращением через this->..., либо обращением через квалифицированное имя IEdge<Key>::.... Для имен типов же применим только второй вариант. И так как тип IEdge<Key> является зависимым, то вот тут-то и вступит в силу правило, требующее указания typename в ссылках на вложенные типы. (см., например, C++ ошибка dependent name is not a type, prefix with 'typename' to indicate a type)

READ ALSO
Установка и использование RHVoice

Установка и использование RHVoice

Сейчас разбираюсь с синтезом речи, самым лучшем вариантом показался RHVoiceУстановил по инструкции в репозитории

238
BOOST C++ установка, проблема

BOOST C++ установка, проблема

ЗдраствуйтеСкачал boost 1

199
Как убрать окно подтверждения печати на термопринтере?

Как убрать окно подтверждения печати на термопринтере?

В java разбираюсь, но с принтерами вожусь впервые

173