наследование указателя на функцию typedef - PullRequest
1 голос
/ 12 августа 2010

У меня может быть указатель на функцию typedef в таком классе:

template<typename T>
class MyClass
{

public:

typedef T (*fptr)(T);

  void doSomething(fptr my_fptr) { /*...*/ }

};

и это прекрасно работает. но если я наследую от такого класса, как показано ниже:

template<typename T>
class MyClass
{

public:

typedef T (*fptr)(T);

  virtual void doSomething(fptr my_fptr) = 0;

};

template<typename T>
class MyOtherClass: public MyClass<T>
{

public:

  void doSomething(fptr my_fptr) { /*...*/ }

};

компилятор жалуется, что fptr не определен. Есть ли способ наследования указателя функции typedefs, как это? Спасибо, Джеймс

Ответы [ 4 ]

4 голосов
/ 12 августа 2010

Проблема не в наследовании, а в том, что шаблон наследуется от экземпляра другого шаблона, передавая свой собственный аргумент шаблона в качестве параметра.То есть он наследуется от зависимого типа (MyClass<T> зависит от типа T).

Язык требует проверки шаблона перед выполнением подстановки типа и во время этого первого проходавсе независимые имена проверены.Когда компилятор видит fptr, он не зависит от типа T, поэтому он пытается найти его вне вашего шаблона как символ уровня пространства имен и завершается ошибкой.Не допускается создание экземпляра MyBase с типом (нет типа для подстановки), и поэтому целое MyBase является неизвестным, и никакие символы не могут быть там найдены (без замены типа компилятор не может знатьсуществует ли конкретная специализация MyBase).

Самое простое решение - добавить локальный typedef:

typedef MyBase<T> base_type;
typedef typename base_type::fptr fptr;

или полностью квалифицировать вызов:

void doSomething( typename MyClass<T>::fptr ) ...
1 голос
/ 12 августа 2010

Вы должны иметь возможность наследовать публичные определения типов, как это.

Вы пробовали что-то подобное, чтобы убедиться, что компилятор знает, что это родительский тип:

void doSomething(typename MyClass<T>::fptr my_fptr) { /*...*/ }
0 голосов
/ 12 августа 2010

Проблема в том, что определение находится в базовом классе, который зависит от параметра шаблона (известного как зависимый базовый класс ); неизвестно, пока не будет создан экземпляр шаблона, каков этот базовый класс; разные специализации могут иметь разных членов. Поэтому вы должны явно указать, что это тип, определенный в базовом классе:

template<typename T>
class MyOtherClass: public MyClass<T>
{
    typedef typename MyClass<T>::fptr fptr;
    // now fptr is available in this class template
};

Чтобы получить доступ к членам зависимого базового класса, вы можете ссылаться на них как MyClass<T>::member или this->member.

0 голосов
/ 12 августа 2010

Я думаю, что компилятору нужно больше информации из-за шаблонов:

попытка typename MyClass<T>::fptr

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...