Доступ к типу указателя функции базовых классов шаблона

StackOverflow https://stackoverflow.com/questions/861133

Вопрос

У меня есть класс, который мне предоставили, и который я действительно не хочу менять, но хочу расширить.Я новичок в области шаблонов и шаблонов, экспериментирующий с шаблоном Decorator, примененным к классу шаблона.Класс шаблона содержит указатель на член (если я правильно понимаю семантику) еще в одном классе.Указатель на член — это десериализатор istream XML.Тип «T» — это тип XML-документа, который необходимо десериализовать.

template <typename T> class B {
public:
  typedef std::auto_ptr<T> MYFUN( 
    std::istream&, const std::string&, const std::string& );

public:
  B<T>( MYFUN* p );

private:
  MYFUN *fptr;
  std::string aString1;
  std::string aString2;

};

Typedef кажется мне странным после прочтения http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5, и тем не менее этот класс, похоже, работает нормально как есть.В предоставленном заголовочном файле нет никаких дополнительных #defines, поэтому для меня это немного загадочно.

Теперь я пытаюсь расширить его как Decorator, потому что хочу немного больше поработать над объектом auto_ptr, возвращаемым MYFUN:

template <typename T>
class D : public class B<T>
{
  D( B<T>::MYFUN *fPtr, B<T> *providedBase ); //compiler complaint
  //Looks like B
  private:
    B* base_;

};

template <typename T>
D<T>::D( B<T>::MYFUN *p, B<T> *base ) //compiler complaint
:
B<T>::B( p ), base_(providedBase)
{ }

При попытке скомпилировать это, я получаю жалобу на синтаксис в двух показанных строках.Ошибка — это что-то вроде «ожидается ')' в *».Нет жалоб на то, что MYFUN не определен.

Когда я переопределяю указатель на член в D с той же сигнатурой, что и в D, т.е.

//change MYFUN to NEWFUN in D)
typedef std::auto_ptr<T> MYNEWFUN( 
    std::istream&, const std::string&, const std::string& );

Это работает.Я предпочитаю не делать этого с каждым D/декоратором, которого я могу сделать из B.Я попытался выполнить определение типа более глобально, но не смог получить правильный синтаксис из-за того, что параметр шаблона не определен.

Это было полезно?

Решение

Ошибка компиляции связана с тем, что компилятор не может определить, что вы говорите о типе.

Пытаться:

D( typename B<T>::MYFUN *fPtr, B<T> *providedBase );

и

template <typename T>
D<T>::D( typename B<T>::MYFUN *p, B<T> *base )

Видеть: раздел шаблонов C++ FAQ Lite подробнее о том, почему это необходимо, но суть в том, что из-за возможности специализации шаблона компилятор не может быть уверен, что B<T>::MYFUN на самом деле относится к типу.

Другие советы

Определение typedef MYFUN в B выполняется с частной видимостью.D не сможет получить к нему доступ.Если вы измените его на защищенный или общедоступный, это будет работать?

template <typename T> class B {
  protected:
    typedef std::auto_ptr<T> MYFUN( 
      std::istream&, const std::string&, const std::string& );
...
};

Проблема, которую я вижу в этом, заключается в том, что B::MYFUN - это частный определение типа.

Следовательно, любой наследующий класс не может получить к нему доступ.

Измените это на:

template <typename T> class B 
{  
public:
   typedef std::auto_ptr<T> MYFUN(     std::istream&, const std::string&, const std::string& );
public:  
   B<T>( MYFUN* p );
private:  
   MYFUN *fptr;  
std::string aString1;  
std::string aString2;
};
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top