klasse nicht geklariert, obwohl sie es sein müsste?!
-
VC hats eben wie gesagt ohne zu meckern übersetzt. Ich konnte mir zwar nicht vorstellen, dass GCC das nicht schafft, habs dann aber trotzdem getestet. Ergebnis: Auch da funktionierts. Siehe hier: http://i51.tinypic.com/28vatl5.png
Den Fehler, dass er kein main findet, wird man natürlich los wenn man das hier macht:
http://i51.tinypic.com/2ccqvxg.png
Offensichtlich hast du also doch noch irgendwo was anderes falsch.
Aber selbst wenn du es findest, empfehle ich in jedem Fall weiterhin, die Definitionen mit in die .hs zu packen, weil es dann einfach viel übersichtlicher wird.
-
Das Problem is ja auch nicht dass mat unbekannt ist sondern lgs. Wenn du z.B. mit #include "lgs.h" startest dann wird als erstes gleich mal mat.h inkludiert welches nach der Definition von mat lgs inkludiert, was nun aber übersprungen wird und dazu führt dass in der Definition von mat<t>::change() lgs unbekannt ist.
Abgesehen davon kann man das mit der Trennung von Deklaration und Implementierung schon so machen nur würde ich dazu raten die Dateien dann eben nicht .cpp zu nennen sondern irgendwas anderes.
-
@Dot: Schau dir doch nochmal genau an, was er da tut, und was der Präprozessor mit seinem Code dann macht. Seine Vorgehensweise ist nicht falsch (Es funktioniert ja, siehe meine Screenshots) sondern nur unnötig kompliziert.

Dieses Verfahren ist halt ein gescheiterter Versuch, auch bei Templates noch alle Definitionen in eine cpp zu packen.
Wenn da jetzt noch andere Memberfunktionen dabei wären, die nicht templatig sind, müssten die konsequenterweise in eine weitere cpp kommen, die dann nirgendwo includiert wird und wie bei Nichttemplategeschichten auch dann erst von Linker drangeknotet wird.
-
ok, das stimmt, bin immer von #include "mat.h" ausgegangen, dann müsste ja eine forward-deklaration von mat in lgs.h punkt abhilfe schaffen.
-
hat funktioniert, danke für die hilfe
-
Darf ich die Auflösung erfahren, warum der gepostete Code bei mir lief und bei dir nicht?

-
Dobi schrieb:
Darf ich die Auflösung erfahren, warum der gepostete Code bei mir lief und bei dir nicht?

Vermutlich weil du mat.h inkludiert hast und nicht lgs.h
-
ja denke auch das daran lag, hab die lgs.h jetzt jedenfalls zu
#ifndef __lgs_h__ #define __lgs_h__ template<class t> class mat; class lgs { public: template<class t> static void change(mat<t> &m, t const &data); }; #include "mat.h" #include "lgs.cpp" #endifgeändert und es funktioniert.
-
dot schrieb:
Dobi schrieb:
Darf ich die Auflösung erfahren, warum der gepostete Code bei mir lief und bei dir nicht?

Vermutlich weil du mat.h inkludiert hast und nicht lgs.h
Ich hatte nix geändert sondern nur den Code, der im Eingangspost stand, in Dateien kopiert, was man auch auf den Screenshots sieht. Naja, mir solls egal sein.

-
Um den Code zu verwenden musst du ihn ja aber in irgendeine Übersetzungseinheit inkludieren. Oder hast du dich von der Tatsache verwirren lassen dass die beiden Dateien mit den Implementierungen auf .cpp enden? Genau darum halte ich es wie gesagt auch für eine extrem schlechte Idee Dateien auf .cpp zu benennen die gar keine Übersetzungseinheiten sind

-
Ah, haha, sehr gut. Hast vollkommen Recht. Das wars. Ich hab die mat.cpp direkt kompiliert, was dann natürlich ging.

-
Dobi schrieb:
Allerdings hat es sich (schon allein der Übersichtlichkeit halber) durchgesetzt, dass man die Definitionen einfach mit in die .h schreibt, die cpp nicht includiert und da nur den Kram drin hat, der nicht sichtbar sein muss. Dann passt es auch wieder zum normalen .h-.cpp-Konzept. Das würde ich auch empfehlen.
Was daran übersichtlich sein soll, kann ich jetzt überhaupt nicht nachvollziehen. In ein headerfile sollen die Definitionen und nichts anderes.
Alle eigentlichen Codes ins cpp. Wenn da was keine Templates drin hat, hat man schnell zwei defines angebracht, so dass sich das cpp auch trotz des mit enthaltenen template codes problemlos kompilieren lässt.
So ist dann aber alles schön so zusammen wie es auch bei allen nicht-Template-Klassen ist.
-
ccpete schrieb:
Was daran übersichtlich sein soll, kann ich jetzt überhaupt nicht nachvollziehen. In ein headerfile sollen die Definitionen und nichts anderes.
Ein Template funktioniert aber nicht nach den "üblichen" Maßstäben, und es ist mit Sicherheit ungewöhnlicher ein include auf eine cpp zu machen, als eine Definition in die Header zu schreiben (und wenn schon, mit einer Endung die auf den Sonderfall hinweist. z.B. tmpl statt cpp).
-
asc schrieb:
Ein Template funktioniert aber nicht nach den "üblichen" Maßstäben,
Wohl war, aber es lässt sich so umsetzen, dass es genauso mit einbezogen werden kann wie eine ganz normale Klasse - Und dies macht in meinen Augen mehr Sinn, als etwas wie
asc schrieb:
(...mit einer Endung die auf den Sonderfall hinweist. z.B. tmpl statt cpp).
Denn ich sehe hier keinen Mehrnutzen. Oder was nützt es mir, wenn ich die Endung sehe und dann nachschauen muss: "scheisse, was ist denn das für n'ding?".
Und wenn ich dann noch Teile separat kompilieren muss, zB wegen einer Spezialisierung, dann soll das nochmals in ein separates File usw usw? Ne Danke, da ist doch der gute alte Aufbau einmal .hpp und einmal .cpp viel angenehmer.
-
ccpete schrieb:
...da ist doch der gute alte Aufbau einmal .hpp und einmal .cpp viel angenehmer.
Ich hoffe das niemand mit deinen Projekten arbeiten muss, und sich erstmal wundert, warum eine cpp inkludiert wird.
Zumal man dann noch in eine ganz andere Falle laufen kann: Die meisten Entwickler erwarten, das ein Include, das in einer cpp gemacht wird, oder ein using namespace, nur in diesem verwendet wird. In diesem Fall gilt dies aber alles nicht. Wehe dem der das nicht beachtet...
-
asc schrieb:
Ich hoffe das niemand mit deinen Projekten arbeiten muss, und sich erstmal wundert, warum eine cpp inkludiert wird.
Wenn er das tut, hat er das gleiche Problem wie mit nem *.tmp^^
Aber für den Gebrauch ists viel intuitiver.asc schrieb:
Zumal man dann noch in eine ganz andere Falle laufen kann: Die meisten Entwickler erwarten, das ein Include, das in einer cpp gemacht wird, oder ein using namespace, nur in diesem verwendet wird. In diesem Fall gilt dies aber alles nicht. Wehe dem der das nicht beachtet...
Das soll ne Falle sein?!
Wie gesagt: Man kann (ohne viel Aufwand) den Code so schreiben, dass sich alles so verwenden lässt als wärs ne ganz normale Klasse. Dass man dann kein using namespace oben hin setzt, versteht sich wohl...

-
ccpete schrieb:
asc schrieb:
Ich hoffe das niemand mit deinen Projekten arbeiten muss, und sich erstmal wundert, warum eine cpp inkludiert wird.
Wenn er das tut, hat er das gleiche Problem wie mit nem *.tmp^^
Aber für den Gebrauch ists viel intuitiver.Naja, wenn die Dateien immer .tempalte oder sonstwas heißen, muss man sich das nur einmal merken und weiß dann Bescheid.
Wenn man das nicht tut, muss man bei jeder cpp erneut gucken, ob es sich um eine eigene Übersetzungseinheit handelt oder das Ding sichtbar ist (schon allein für die von dir erwähnte namespace-Frage). Für meinen Geschmack ist das eher ne Frickellösung, weil kein Compiler "export" hinbekommen hat.
Natürlich ist es Geschmackssache, aber warum man unbedingt an "Keine Definitionen in Hs" festhalten sollte, verstehe ich nicht. Für mich, wie für viele andere auch, ist das andere halt intuitiver.
Eigentlich sind es ja eh auch gar keine Definitionen, sondern Definitionstemplates.
Anstelle von "Hs für Deklarationen, cpps für Definitionen" kann mans auch als "Hs für sichtbares, cpp für rangelinktes" beschreiben.
Dann hat man Templates und Inlines schon drin.
Apropos: Nach deinem Konzept dürfte man gar keine Inlinememberfunktionen haben, oder? :p
-
Dobi schrieb:
Naja, wenn die Dateien immer .tempalte oder sonstwas heißen, muss man sich das nur einmal merken und weiß dann Bescheid.
Wenn man das nicht tut, muss man bei jeder cpp erneut gucken, ob es sich um eine eigene Übersetzungseinheit handelt oder das Ding sichtbar ist (schon allein für die von dir erwähnte namespace-Frage).
Naja, das ist doch gar nicht nötig. Du kannst mit define guards in der .cpp die Templatefunktionen sauber von "normalen" Funktionsdefinitionen trennen, dafür brauchst du nur ein einziges define. Der Teil mit den Templatefunktionen sieht dann ganz so aus, wie er das in der .hpp auch würde, und der andere sieht aus wie n'ganz normales .cpp File. Um using und andere Dinge musst du dich da nicht mehr kümmern. Dann kannst du wie mit anderen Klassen dein Templateheaderfile includen (das selber dann nur den template Teil der .cpp included) und ausserdem für den anderen Teil einfach die .cpp kompilieren ohne dass sich da was beisst
Dobi schrieb:
Für meinen Geschmack ist das eher ne Frickellösung
Stimmt in dem Sinne, dass es natürlich etwas aufwändiger ist, als alles in den header reinzuschreiben.
Dobi schrieb:
Natürlich ist es Geschmackssache, aber warum man unbedingt an "Keine Definitionen in Hs" festhalten sollte, verstehe ich nicht.
Um dies gehts mir ja gar nicht grundsätzlich. Wie gesagt Geschmackssache, aber ich persönlich finde es angenehm, dass ich, wenn ich die Definition einer Funktion suche, ins .cpp-File schauen kann und wenn ich nur die Deklaration benötige, diese im .hpp-File finde. Und da muss ich mich dann eben nich drum kümmern, ob die Klasse da jetzt n'Template war oder nicht...
Und dasselbe auch für die Benützung, Template oder nicht, Spezialisierungen oder nicht, ich kann immer die gleiche Regel anwenden (Stichwort:makefile): Den header includen, das .cpp kompilieren und linken.
Mag sein, dass das nicht üblich ist, aber praktikabler finde ich dies jetzt durchaus.
-
Ok. Jetzt interessiert mich noch, wie du das mit den Inlinememberfunktionen in normalen Klassen machst.

-
Dobi schrieb:
...Für meinen Geschmack ist das eher ne Frickellösung, weil kein Compiler "export" hinbekommen hat...
Diese Aussage stimmt nicht ganz, mindestens der Comeau Compiler hat dies tatsächlich (mit sehr langer Entwicklungszeit) hinbekommen, nun fällt das mit dem neuen Standard aber eh wieder weg (Dürfte für den Comeau-Entwickler recht ärgerlich sein, anderseits ärgere ich mich wiederum über die extrem langen Zyklen beim Comeau...).