🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
4 messages
4 total messages Started by Thorsten Gau Sun, 24 Sep 1995 11:55
instantiation of template - incomplete type
#468
Author: Thorsten Gau
Date: Sun, 24 Sep 1995 11:55
36 lines
1178 bytes
Hallo,

ich habe Probleme mit folgendem Code. Der VisualAge C++ compiliert ihn ohne
Probleme, doch gcc 2.6.3 mag sowas gar nicht. Hilft mir da vielleicht ein
Upgrade auf 2.7.0 oder kann ich da irgendwie drumrum programmieren?

template<class T> class L
{
private:
   T data;

public:
   L() {}
};

class A
{
public:
   A() {}
   L<A> children();
};

tmplprob.cc:4: field `data' has incomplete type
tmplprob.cc:4:   in instantiation of template `L<A>'

Wäre toll, wenn Du per Mail antworten könntest.
Vielen Dank

	Thorsten


-- 
==============================================================================
Thorsten Gau --- Neu Wulmstorf, Germany --- VOICE: +49 40 / 700 52 96   * *
EMail: gau_t@gauhh.hanse.de / gau_t@informatik.fh-hamburg.de             |
2B or not 2B... gives FF    PGP-Key on demand !                        \___/
Re: instantiation of template - incomplete type
#471
Author: Ullrich von Bassewitz
Date: Mon, 25 Sep 1995 20:19
26 lines
1341 bytes
Thorsten Gau (gau_t@gauhh.hanse.de) wrote:
> ich habe Probleme mit folgendem Code. Der VisualAge C++ compiliert ihn ohne
> Probleme, doch gcc 2.6.3 mag sowas gar nicht. Hilft mir da vielleicht ein
> Upgrade auf 2.7.0 oder kann ich da irgendwie drumrum programmieren?

g++ und Templates - zwei Welten begegnen sich...

Mein Tip: Probier's mal mit g++ 2.7.0. Die Versionen 2.6.x machen in
Zusammenhang mit Templates jede Menge Aerger. Garantieren kann ich
allerdings auch mit 2.7.0 nichts.

> Wäre toll, wenn Du per Mail antworten könntest.

Solche Formulierungen werden normalerweise nicht so gerne gesehen. Wenn ich
mir die Muehe mache, News zu lesen um Fragen zu beantworten (und
dazuzulernen :-), dann kannst Du Dir die Muehe machen, News zu lesen um die
Antworten auf Deine Frage zu lesen.

Gruss


        Uz


-- 
Ullrich von Bassewitz                              uz@ibb.schwaben.com
Re: instantiation of template - incomplete type
#488
Author: Olaf Pfohl
Date: Thu, 28 Sep 1995 14:00
60 lines
1556 bytes
Thorsten Gau (gau_t@gauhh.hanse.de) wrote:

: ich habe Probleme mit folgendem Code. Der VisualAge C++ compiliert ihn ohne
: Probleme, doch gcc 2.6.3 mag sowas gar nicht. Hilft mir da vielleicht ein
: Upgrade auf 2.7.0 oder kann ich da irgendwie drumrum programmieren?

: template<class T> class L
: {
: private:
:    T data;

: public:
:    L() {}
: };

: class A
: {
: public:
:    A() {}
:    L<A> children();
: };


Nun ja, ich finde dieses Klassendesign an sich nicht so toll: du gibst als
template-Argument die Klasse an, in der das Klassen-Member selbst enthalten
ist...das ist ja rekursiv und eine Fehlermeldung "uber unvollst"andige Klasse
eigentlich genau die richtige Meldung.

Besser w"are es, eine Basisklasse einzuf"uhren, von der abgelitten wird, und
welche auch als template-Argument dienen kann:


template <class T> class L
{
private:
  T data;

public:
  L() {}
};

class B
{
  // ...
};


class A: public B
{
public:
  A() {}
  L<B> children();
};



Olaf

--
(signature intentionally left blank)
Re: instantiation of template - incomplete type
#503
Author: Karl-Heinz Krause
Date: Sun, 01 Oct 1995 18:40
122 lines
4427 bytes
Am 28. Sep 1995 schrieb Olaf Pfohl (pfohl@ips.cs.tu-bs.de) in
Beantwortung einer Anfrage von Thorsten Gau:

>Thorsten Gau (gau_t@gauhh.hanse.de) wrote:

>: ich habe Probleme mit folgendem Code. Der VisualAge C++ compiliert ihn ohne
>: Probleme, doch gcc 2.6.3 mag sowas gar nicht. Hilft mir da vielleicht ein
>: Upgrade auf 2.7.0 oder kann ich da irgendwie drumrum programmieren?

>: template<class T> class L {
>:     T data;
>:   public:
>:     L() {}
>: };

>: class A {
>:   public:
>:     A() {}
>:     L<A> children();
>: };


>Nun ja, ich finde dieses Klassendesign an sich nicht so toll: du gibst als
>template-Argument die Klasse an, in der das Klassen-Member selbst enthalten
>ist...das ist ja rekursiv und eine Fehlermeldung "uber unvollst"andige Klasse
>eigentlich genau die richtige Meldung.

>Besser w"are es, eine Basisklasse einzuf"uhren, von der abgelitten wird, und
>welche auch als template-Argument dienen kann:


>template <class T> class L {
>  private:
>    T data;
>  public:
>    L() {}
>};

>class B {
>  // ...
>};

>class A: public B {
>  public:
>    A() {}
>    L<B> children();
>};


Die Kritik am Klassendesign ist vollkommen unberechtigt. Natürlich ist
das ganze rekursiv, aber Rekursivität ist beim Programmieren etwas
ganz normales. Un die Fehlermeldung über unvollständige Klassen ist
nicht angemessen.

Indirekt ist A ja sowas ähnliches wie

	struct A {
	    A child();
	};

und sowas ist in C++ durchaus erlaubt!

Das Einfügen der Zwischenklasse B ist ein typischer "Workaround" um
Compilermängel zu umgehen. Wenn´s funktioniert: gut. Aber wenn ein
Compiler es nötig macht, solche Umwege zu gehen, statt die Sache
direkt so zu formulieren, wie man es haben will, dann ist das immer
als Compilerfehler anzusehen und hat nichts mit schlechtem
Programmierstil zu tun. Im Gegenteil, eigentlich sind solche
Workarounds schlechter (aber leider notwendiger) Programmierstil.

Der Vorschlag mit der Zwischenklasse B funktioniert außerdem nicht
immer. Da "child" ja jetzt den Typ L<B> hat, muß jede Operation, die
man auf "child" anwenden will, bereits in B definiert sein. Was ist
aber wenn in solch einer Operation ebenfalls auf "child" zugegriffen
werden soll? In B gibt es ja kein "child". (Soweit die Kritik an der
Kritik.)

Der Hauptgrund des Problems ist übrigens, daß es bisher keine wirklich
saubere Definition von Templates in C++ gibt, insbesondere was den Ort
der Instanziierung angeht. Bisher gibt es nur Aussagen von Stroustrup,
wie es ungefähr funktionieren soll, und deshalb verhalten sich die
verschiedenen Compiler da alle etwas anders. Borland C++ 4.5 hat
jedenfalls dasselbe Problem.

Ich habe in "The Design and Evolution of C++" folgende Aussage
gefunden (15.10.2): "The original definition says ... that the point
of instantiation is just before the global declatation in which a
template is first used."

In unserem speziellen Fall taucht L<A> erstmals in der Definition von
A auf. Also erfolgt die Instanziierung unmittelbar vor der Definition
von A. Den vom Compiler erzeugten Code muß man sich dann etwa so
vorstellen:

	class A;
	// Hier erfolgt Instanziierung von L<A>.
        // class L<A> {
	//     A data;
	//     ...
        // };
	class A {
	    // Hier wird A erst definiert.
	};

Die Instanziierung erfolgt also, bevor A vollständig definiert ist. In
der Instanziierung wird jedoch A benutzt um eine Variable zu
definieren, und das geht nicht. Die Definition eines Zeigers oder
einer Referenz des Typs A wäre dagegen erlaubt.

Der einzige Workaround, der mir einfällt und der zumindes in Borland
C++ 4.5 funktioniert, ist

	template<class T> class L {
	    T *pData;
	  public:
	    L(): pData(new T) {}
	    ~L() { delete pData; }
	};



Viele Grüße von Karl-Heinz
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads