Frage

Ich habe eine Klasse, die ich zur Verfügung gestellt worden, dass ich wirklich ändern will nicht, aber ich möchte zu verlängern. Ich bin ein Muster und Vorlage Neuling mit einem Dekorierermuster zu einer Template-Klasse angewandt zu experimentieren. Template-Klasse enthält einen Zeiger-to-Mitglied noch in einer anderen Klasse (wenn ich die Semantik richtig verstehe). Der Zeiger-to-Mitglied ist der Deserializer eines XML-istream. Der Typ ‚T‘ ist die Art von XML-Dokument deserialisiert werden.

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;

};

Die typedef sieht mir seltsam nach http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5 , und doch scheint diese Klasse gut zu funktionieren, wie sie ist. Es gibt keine zusätzlichen #defines in der Header-Datei zur Verfügung gestellt, so ist dies ein wenig geheimnisvoll zu mir.

Jetzt versuche ich, sie zu verlängern, als Ausstatter, weil ich ein bisschen mehr Arbeit auf dem auto_ptr-Objekt von myfun zurückgegeben tun:

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)
{ }

Wenn diese zu kompilieren versuchen, erhalte ich eine Syntax Beschwerde an den beiden Linien dargestellt. Fehler sind so etwas wie „erwartet‚)‘auf *“. Es gibt keine Beschwerde über myfun nicht definiert ist.

Als ich neu definiert den Zeiger-to-Mitglied in D mit derselben Signatur wie in D, d.h.

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

Das funktioniert. Ich ziehe das nicht haben für jeden D / Decorator tun ich von B. machen könnte ich die typedef mehr global führen versuchte, konnte aber die Syntax rechts aufgrund der Template-Parameter undefiniert nicht erhalten.

War es hilfreich?

Lösung

Der Compiler-Fehler ist auf die Tatsache zurückzuführen, dass der Compiler kann nicht sagen, Sie sprechen von einer Art.

Versuchen:

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

und

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

Siehe auch: die Vorlagen Abschnitt des C ++ FAQ Lite um weitere Informationen darüber, warum dies notwendig ist, aber die Zusammenfassung ist, dass wegen der Möglichkeit der Template-Spezialisierung, gibt es keine Möglichkeit für den Compiler, dass B<T>::MYFUN tatsächlich auf eine Art bezieht sich sicher sein ist.

Andere Tipps

Die Definition des myfun typedef in B ist mit einem eigenen Sicht getan. D wird es nicht zugreifen können. Wenn Sie es geschützt oder öffentlich ändern, wird es dann funktionieren?

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

Das Problem, das ich mit diesem zu sehen ist, dass B :: myfun ist ein privat typedef.

Daher wird jede Klasse kann inheriting nicht darauf zugreifen.

Ändern Sie diese an:

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;
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top