C++ Templates und virtuelle Methoden

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.

C++ Templates und virtuelle Methoden

Beitragvon Top-OR » 04.08.2016, 20:32

Hallo Freunde der Sonne!

Ich habe eine Frage zum Thema C++/Templates/Vererbung. Ich ahne, dass ich mich später dafür schämen werde, sowas gebaut und dann noch gefragt zu haben, aber es lässt mir keine Ruhe:

Nun: Ich lese immer, dass "virtual" methods und Templates nicht zusammenpassen, da das eine zur Laufzeit stattfindet und das andere zur Compile-Time.
Jetzt habe ich folgendes Scenario (mal vereinfacht/etwas synthetisiert):

Code: Ansicht erweitern :: Alles auswählen


//definiere Template, welches als Basis-Klasse/Basis-Template für andere Templates gilt
template <typename T> class TBaseCollection {
public:
[...]
virtual int getCount () const = 0;
virtual const T& operator[] (int) const = 0;
void doConvinientAndCommonStuff() {
[do something here which is common for all collections]
int a = getCount(); // call virtual method defined here (to be implemented in derived template class)
[...]
}
};

// leite von Basistemplate ab und implementiere abstrakte/virtuelle Methoden
template <typename T> class TArray : public TBaseCollection<T> {
public:
int getCount () const {
return (10); // silly example, but does the job
}
const T& operator [](int Index) const {
return Items[Index]; // just return the simple item here without having boilerplate code here
}
private:
T m_Items[10]; // silly example with static content
};


Ich definiere quasi im Basistemplate Methoden , die in der Implementierung des Basistemplates gecallt werden, aber erst im der ableitenden Template implementiert werden.
Wie gesagt lese ich immer (auch von Stroustrup persönlich), das virtuelle Methoden und Templates in Kombi sinnlos sind. Ich erkenne hier aber einen Sinn und es funktioniert auch.

Mein Code kompiliert mit MSVC und dem GCC gut und beides läuft geschmiert - wie es sein soll.

Nun meine Frage: Funktioniert es nur zufällig, weil der Kompiler dem Ganzen doch irgendeinen Sinn gibt, der ursprünglich nicht definiert ist?

Wenn mein Ansatz falsch ist, wie könnte ich es richtig machen?

Klar könnte ich "int getCount() const" in eine abstrakte Basisklasse (kein Template) ziehen, von der dann das Basis-Template TBaseCollection selbst ableitet. Aber was mache ich dann mit "const T& operator[] (int) const = 0;" , was ja typbezogen sein muss und daher Teil des Templates sein sollte.

Geht da was mit meinem Verständnis von "virtuelle Methoden" (Benutzung von schlüsselwortes virtual) und "abstrakten Methoden" (nicht impementiert: "void blah() = 0" ) schief? Wo ist mein Denk-/Designfehler? Wie geht es "richtiger"? *Confused*
Zuletzt geändert von Top-OR am 05.08.2016, 10:56, insgesamt 1-mal geändert.
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Jens H.
Establishment
 
Beiträge: 307
Registriert: 02.03.2011, 17:32
Wohnort: Esslingen/Dessau

Re: C++ Templates und virtuelle Methoden

Beitragvon DerAlbi » 04.08.2016, 22:13

Ich finde das gut so, wie es ist. Ich glaube, dass du da irgendwelchen Leuten aufgelaufen bist, die meinen, es gäbe strikte Designdogmata die man nicht tun dürfte, obwohl man sie offensichtlich implementieren kann. Warum ein Stroustrup so etwas sagt, weiß ich nicht.. vermutlich ist kein Anwendungsszenario dafür eingefallen. Ich erkenne bei dir auch den Sinn dahinter und ich hab das auch schon so gemacht. Natürlich kann man von Templates ganz normal ableiten. Man kann auch von NormalKlasse->TemplateKlasse oder von TemplateKlasse->Normalklasse ableiten. Je nach Anwendung.
Mach noch ein Goto in den Quelltext, vorzugsweise in das innere von zwei verschachtelten Schleifen mit Sprungziel nach außen :-) Dann kommen die Schreikinder alle aus ihren Löchern und du weißt auf wen du nicht hören musst :-)
DerAlbi
Establishment
 
Beiträge: 177
Registriert: 20.05.2011, 05:37

Re: C++ Templates und virtuelle Methoden

Beitragvon Top-OR » 04.08.2016, 23:01

Moin Albi!

Danke für deine Antwort - so habe ich zumindest mal das Gefühl, dass es ein total abwegiger Bullshit ist, den ich da gebaut habe - zumal er ja zumindest sinnvoll erscheint.

Ich hoffe auch noch, dass diese Aussage zu "C++ templates virtual methods" im Netz (einfach mal googlen -> StackOverflow & Co) in der Summe von Leuten kommen, die die Handhabung Ihrer Programmiersprache mal wieder zu religiös nehmen bzw. sich keinen sinnvollen Use Case vorstellen können.

Ich bin drauf gekommen, als ich dieses Video von Bjarne Strouchstrup himself angesehen habe:

Das Vid ist ja eher ne schnelle Tour durch die Sprache mit eine paar Kommentaren vom "Erfinder" der Sprache selbst. Aber an einer Stelle (weiss die Minute nicht mehr) sagt er eben auch sowas in der Richtung, dass das Mischen von Templates und virtuellen Methoden nicht so toll wäre (im Sinne von sinnlos) - so habe ich das zumindest verstanden. Und wenn der Papa von C++ das so sagt, nehme ich das schon ernster, als wenn ichs nur in ein paar Foren von ein paar Sprachfundamentalisten aufgeschnappt hätte... Und forsche mal nach. ;-)

Andererseits sind die Kombinationsmöglichkeiten bestimmter Konstrukte so vielfältig, dass auch der "Erfinder" nicht alle Use Cases vorhersehen kann und Dinge vielleicht manchmal doch sinnvoll sind.

Naja ... Verallgemeinerungen sind eben immer falsch ... *Dooooh*

Also .. danke erstmal soweit.
Die ursprüngliche Befürchtung, etwas gebaut zu haben, was nur durch "undefinierte Kompilereffekte zufällig funktioniert" ist erstmal entschärft.

Vielleicht meldet sich noch der eine oder andere mit Senf dazu (würde ich begrüßen)...
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Jens H.
Establishment
 
Beiträge: 307
Registriert: 02.03.2011, 17:32
Wohnort: Esslingen/Dessau

Re: C++ Templates und virtuelle Methoden

Beitragvon DerAlbi » 05.08.2016, 04:07

Also ich habe mir das Video gerade angeschaut :-) Cool.
Es wurde aber com Chef persönlich erstmal keine Aussage dahingehend getroffen, was ok ist und was nicht. Er sagt sogar explizit (allerdings politisch korrekt), dass die Leute, die sowas pauschalisieren Deppen ohnesgleichen sind.
In der Q&A-Sektion gibt es eine Frage zu Konstrukten wie deinen, weil sie für Anfänger (oder einsteiger in große Projekte) eine Hürde darstellen - was auch stimmt. Aber das bedeutet nicht, dass derartige Konstrukte schlecht sind. Wenn sie nötig sind, sind die halt nötig.

Was allerdings gesagt wurde ist, dass Vererbung natürlich durch die zusätzliche Indirektion das Inlining und damit die Performance killt. Gerade Templates schreibt man oft mit dem Hintergrund, dass man typenspezifische (compoiletime-)Optimierungen direkt vom Compiler incl inlining usw. will. Das paart sich halt nicht gut mit Vererbung.
Als Beispiel wird dein überladener []-Operator total vor die Hunde gehen (im Verlgeich mit einem direkten Speicherzugriff / üblichen []-Operator). Aber wenn es dein Inferface so verlangt ist es dennoch eine elegante Lösung. Man muss als Programmierer einfach wissen, welche Tradeoffs man eingeht.
DerAlbi
Establishment
 
Beiträge: 177
Registriert: 20.05.2011, 05:37

Re: C++ Templates und virtuelle Methoden

Beitragvon dot » 05.08.2016, 09:23

Dein Code ist an sich nicht falsch und sollte funktionieren. Die Frage ist allerdings, was genau du damit erreichen willst. Wofür genau brauchst du den Polymorphismus durch diese TBaseCollection?
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1601
Registriert: 06.03.2004, 19:10

Re: C++ Templates und virtuelle Methoden

Beitragvon Top-OR » 05.08.2016, 10:38

dot hat geschrieben:Dein Code ist an sich nicht falsch und sollte funktionieren. Die Frage ist allerdings, was genau du damit erreichen willst. Wofür genau brauchst du den Polymorphismus durch diese TBaseCollection?


"Brauchen" tu ich die nicht. Ich finde die Idee charmant, dass alle Collections, seien es Listen, Arrays, Pointer(sind in meinem Universum Arrays, die Ihren Speicher nicht selbst besitzen/verwalten), Hashmaps etc. ein grundlegendes gemeinsames Interface haben und ich z.B. darauf aufbauend die Inhalte einer Hashmap(Values) direkt in einen Array kopieren kann; und das in Standard-Notation:

Code: Ansicht erweitern :: Alles auswählen
ListenObjekt = ArrayObjekt;


Ich finde, das erhöht die Lesbarkeit (für den Preis, dass es vielleicht langsamer ist) in den höheren Abstraktionsebenen, die das Zeug eben nur noch benutzen. Meine Codebase erreicht langsam einen Umfang/Level, wo ich Lesbarkeit pushen muss und Geschwindigkeit (im aktuellen Use Case) opfern kann.

Ich finde es gut, wenn gewisse Containerklassen eben durch ein Interface standardisierte Zugriffsmethoden haben, die bei allen Typen von Containern zumindest ein gemeinsames Ergebnis liefern (Wenn auch u.U. langsamer).

Außerdem: So kann ich, wenn ich merke, dass ich für eine gewisse Anwendung lieber eine andere Softe von Container brauche, den Container austauschen, ohne die benutzende Implementierung, die den Container befüllt oder leersaugt, zu ändern. Sie operiert dann auf dem kleinsten gemeinsamen Interface der Containerklassen und muss nicht wissen, ob es ein Array, Liste oder ein Pointer ist.

Oder im Beispiel von oben:
Ich will, dass alle Container die selbe Methode "doConvinientAndCommonStuff()" haben, die immer (möglichst) gleich reagiert.
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Jens H.
Establishment
 
Beiträge: 307
Registriert: 02.03.2011, 17:32
Wohnort: Esslingen/Dessau

Re: C++ Templates und virtuelle Methoden

Beitragvon Spiele Programmierer » 05.08.2016, 11:55

Erstmal: Was du gebaut hast scheint mir völlig legitim.

Ich stimme aber Dot zu: Wozu das ganze?
Standardisierter Zugriff ist eine feine Sache, allerdings wirst du mit dem Interface zB. keine Hashmaps ansprechen können, weil du dich mit getCount dem int im operator[] auf Arrays beschränkst. (Besser wäre übrigens size_t, weil du dann zB. auf 64 Bit entsprechend skalierst und sonst Konvertierungswarnungen auftreten, wenn du es zB. mit Pointern, Iteratoren oder std:: Containern verbindest die alle size_t/ptrdiff_t verwenden)

Standardisierten Zugriff kannst du allerdings auch ohne virtual calls haben. Jeder Container hat einfach die selben Zugriffsmethoden. So wie die std:: Container.

Ich finde die Idee charmant, dass alle Collections, seien es Listen, Arrays, Pointer(sind in meinem Universum Arrays, die Ihren Speicher nicht selbst besitzen/verwalten)

Für diesen Zweck würde ich dir eine einfache "array_view" Klasse nahelegen. (Wird in der neusten Reinkarnation auch manchmal span genannt.) Also eine Klasse die einfach zwei Pointer (begin und end) besitzt und die üblichen Container Methoden (operator[], size, empty, begin, end, etc.) sowie slice Methoden definiert. Meine Implementierung hat gerade mal 400 Zeilen, so kompliziert ist das nicht. Damit hast du ein Interface für alle Listen, egal woher sie stammen. std::vector, std::array, Fixed Size C Arrays, etc. kannst du implizit konvertierbar zu dieser Klasse machen. Ich kann dir sagen, dass diese Klasse mir unglaublich viel Zeit und Ärger gespart hat, dadurch dass ich nicht mehr einzeln einen Pointer und die Länge übergeben muss. Außerdem kann man in die Klasse im operator[] ein paar Debug Assert Range Checks reinpacken. Das tut Wunder. Nur Linked Lists kann man damit nicht darstellen: Allerdings die passen in dein "TBaseCollection" Interface eben so wenig und in der Regel lässt man eh besser die Finger von Linked Lists.

Weil dir scheinbar sehr viel an der Meinung von Stroustrup liegt: In den C++ Core Guidelines empfiehlt er diese Klasse und ich habe irgendwo mal ein Video von ihm gesehen, in dem er sich darüber aufgeregt hat das diese einfache Klasse es noch nicht in die STL geschaft hat.
Spiele Programmierer
Establishment
 
Beiträge: 341
Registriert: 23.01.2013, 16:55

Re: C++ Templates und virtuelle Methoden

Beitragvon Top-OR » 05.08.2016, 13:22

Hi Spiele Programmierer.

Oha - viel Stoff. Danke für die Einschätzung. Also...

Spiele Programmierer hat geschrieben:Erstmal: Was du gebaut hast scheint mir völlig legitim.

Genau das interessiert mich auf einem technischen Level...

Spiele Programmierer hat geschrieben:Ich stimme aber Dot zu: Wozu das ganze?

Diese Frage stelle ich mir seit 20 Jahren, seit ich damals unter DOS in Pascal perspektivisch korrekte Software-Polygonrasterizer nachprogrammiert habe. Diese Frage trifft auf alle Betrachtungsebenen meines Hobby-Projektes zu. Ich beantworte sie seit einigen Jahren auch für mich selbst mit:
"Weil ich es kann". (im Sinne von technisch möglich) Es entspannt mich einfach. Sinnlos, aber entspannend - Hobby eben.

Spiele Programmierer hat geschrieben:Standardisierter Zugriff ist eine feine Sache, allerdings wirst du mit dem Interface zB. keine Hashmaps ansprechen können...,

Falsch .. mache ich bereits seit Jahren und es funktioniert ja. Diese Code-Fragment sind ja nur exemplarischer Peusocode.

Spiele Programmierer hat geschrieben: ... weil du dich mit getCount dem int im operator[] auf Arrays beschränkst. (Besser wäre übrigens size_t, weil du dann zB. auf 64 Bit entsprechend skalierst und sonst Konvertierungswarnungen auftreten, wenn du es zB. mit Pointern, Iteratoren oder std:: Containern verbindest die alle size_t/ptrdiff_t verwenden)

Ich glaube, da komme ich erst im nächsten Leben zu.

Spiele Programmierer hat geschrieben:Standardisierten Zugriff kannst du allerdings auch ohne virtual calls haben. Jeder Container hat einfach die selben Zugriffsmethoden. So wie die std:: Container.


Ne, ich glaube, einer von uns beiden versteht den anderen gerade nicht (nicht zynisch gemeint).
Es geht darum, dass die Implementierungen, die auch der Collection arbeiten, nur das Interface (abstrakte Basisklasse unter TCollection, quasi ICollection) kennen und damit operieren. Es geht nicht darum, dass die Methoden "nur gleich heissen", dass ich sie besser verstehe.

Spiele Programmierer hat geschrieben:
Ich finde die Idee charmant, dass alle Collections, seien es Listen, Arrays, Pointer(sind in meinem Universum Arrays, die Ihren Speicher nicht selbst besitzen/verwalten)

Für diesen Zweck würde ich dir eine einfache "array_view" Klasse nahelegen. (Wird in der neusten Reinkarnation auch manchmal span genannt.) Also eine Klasse die einfach zwei Pointer (begin und end) besitzt und die üblichen Container Methoden (operator[], size, empty, begin, end, etc.) sowie slice Methoden definiert. Meine Implementierung hat gerade mal 400 Zeilen, so kompliziert ist das nicht. Damit hast du ein Interface für alle Listen, egal woher sie stammen.


Ja, sowas habe ich auch, heisst eben seit Jahren Pointer (bissel irreführendes naming) bei mir (Verwaltet Beginn und Ende und macht Range Checks, ohne den Speicher zu Ownen und kann von echt vielen fachlichen Klassen als "Zugriffmedium" auf Speicher ausgespuckt werden). Das hat aber Nichts damit zu tun, dass dieser Pointer UND die Collections selbst eben ein gemeinsames Interface implementieren.

Spiele Programmierer hat geschrieben:std::vector, std::array, Fixed Size C Arrays, etc. kannst du implizit konvertierbar zu dieser Klasse machen. Ich kann dir sagen, dass diese Klasse mir unglaublich viel Zeit und Ärger gespart hat, dadurch dass ich nicht mehr einzeln einen Pointer und die Länge übergeben muss. Außerdem kann man in die Klasse im operator[] ein paar Debug Assert Range Checks reinpacken. Das tut Wunder.


Ich habe mir die eigenen Container mal gebaut, um zu lernen, was da eigentlich dahintersteckt und "wie man Templates benutzen kann". Seit Jahren basieren meine Higher-Level Entwicklungen fast nur noch auf dem eigenen Krams. Bitte NICHT nach dem Sinn fragen .. den gibt es nicht: Eben nur "weil ich es kann". Im Berufsleben bin ich nach 10 Jahren Entwicklung ins User Department im Konzernumfeld gewechselt und würde jedem Entwickler/IT-Projektleiter, der uns vorschlägt, das Rad neu zu erfinden [wie ich es auch gerne mache ;-)], sofort die Finger und Beine brechen (lassen). Dort ist das Leben ergebnisorientierter. Aber Daheim gönne ich mir den Luxus des "selbst frickelns" zu meiner persönlichen Entspannung. Die Frage ist auch, warum bauen wir Spiele - wir könnten ja welche kaufen. Warum spielen wir? Wir könnten ja nen Film gucken. Aus meiner Sicht ist die Grenze zum "Warum" (im Hobbybereich) völlig willkürlich. ;-) Ich trenne da bewusst Beruf und Hobby.

Spiele Programmierer hat geschrieben:Nur Linked Lists kann man damit nicht darstellen: Allerdings die passen in dein "TBaseCollection" Interface eben so wenig und in der Regel lässt man eh besser die Finger von Linaked Lists.

Siehste ... ich kann das. Hashmaps auch (zumindest für die Values - Keys ignoriere ich in meinem Universum großzügig). Du siehst hier ja nur exemplarischen Code...

Spiele Programmierer hat geschrieben: Weil dir scheinbar sehr viel an der Meinung von Stroustrup liegt: In den C++ Core Guidelines empfiehlt er diese Klasse und ich habe irgendwo mal ein Video von ihm gesehen, in dem er sich darüber aufgeregt hat das diese einfache Klasse es noch nicht in die STL geschaft hat.

Was heisst "viel dran liegen". Ich unterstelle ihm, dass er sich als "Erfinder der Sprache" eben mit den vielen Details schon beschäftigt hat, über die "ich" erst Jahre später stolpere. Cool, danke! Da schau ich mir mal an. Thx!

Mir ist nur wichtig, zu wissen, wenn ich hier "technisch kompletten Bullshit" gebaut hätte...
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Jens H.
Establishment
 
Beiträge: 307
Registriert: 02.03.2011, 17:32
Wohnort: Esslingen/Dessau

Re: C++ Templates und virtuelle Methoden

Beitragvon dot » 05.08.2016, 13:47

Top-OR hat geschrieben:
Spiele Programmierer hat geschrieben:Nur Linked Lists kann man damit nicht darstellen: Allerdings die passen in dein "TBaseCollection" Interface eben so wenig und in der Regel lässt man eh besser die Finger von Linaked Lists.

Siehste ... ich kann das. Hashmaps auch (zumindest für die Values - Keys ignoriere ich in meinem Universum großzügig). Du siehst hier ja nur exemplarischen Code...

Würd mich interessieren, wie genau du das machst. Ich seh jedenfalls keinen sinnvollen Weg, sequentielle und assoziative Container hinter ein gemeinsames Interface zu packen. Was auch immer für eine technische Lösung du dafür gestickt haben magst, sowas ist auf konzeptioneller Ebene völlig daneben... ;)

Top-OR hat geschrieben:
Spiele Programmierer hat geschrieben: Weil dir scheinbar sehr viel an der Meinung von Stroustrup liegt: In den C++ Core Guidelines empfiehlt er diese Klasse und ich habe irgendwo mal ein Video von ihm gesehen, in dem er sich darüber aufgeregt hat das diese einfache Klasse es noch nicht in die STL geschaft hat.

Was heisst "viel dran liegen". Ich unterstelle ihm, dass er sich als "Erfinder der Sprache" eben mit den vielen Details schon beschäftigt hat, über die "ich" erst Jahre später stolpere. Cool, danke! Da schau ich mir mal an. Thx!

Mir ist nur wichtig, zu wissen, wenn ich hier "technisch kompletten Bullshit" gebaut hätte...

Hängt davon ab, was du unter "technisch" verstehst. Es ist soweit korrekt als dass es korrektes C++ ist. Besonders toll ist es aber nicht... ;)
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1601
Registriert: 06.03.2004, 19:10

Re: C++ Templates und virtuelle Methoden

Beitragvon Top-OR » 05.08.2016, 14:12

dot hat geschrieben:Würd mich interessieren, wie genau du das machst. Ich seh jedenfalls keinen sinnvollen Weg, sequentielle und assoziative Container hinter ein gemeinsames Interface zu packen.

Echt nicht? Du kannst du nicht vorstellen, dass man für eine Menge von gleichen und diskreten Objekten eine Halbordnungsrelation definiert, denen diese Objekte genügen und anhand der du dann ein „>, „<“ oder ein „==“ ausführen kannst?
Da kannste doch alles nehmen, vorzusweise etwas, was den technischen Interna des Containers nahe steht und was deterministisches Verhalten an den Tag legt. Ich glaube, ich würde sogar auf einem Container Namens CAlterSchrankAufDemDachbodenMitKramsDrinne eine brauchbare Abzähllogik definieren, die sich deterministisch verhält. Wenn du die hast, ist auch operator[] kein Problem mehr. getCount() sowieso nicht.

Wenn du das kannst, kannst du sie auch abzählen und sie kommen bei jedem „Abzählvorgang“ in der gleichen Reihenfolge.

So kann man zumindest eine Hashmap gut leersaugen bzw. ändern. Neu befüllen geht natürlich (bei Hashmaps) nicht, es sei denn, man denkt sich beim Befüllen der Values aus einer Liste noch Keys aus. Das wäre aber wirklich "blöd". Sowas wie "Listenobjekt = HashmapObjekt" kann ich, "HashmapObjekt = Listenobjekt" nicht, da Informationen fehlen.

dot hat geschrieben:Was auch immer für eine technische Lösung du dafür gestickt haben magst, sowas ist auf konzeptioneller Ebene völlig daneben... ;)


Für mich als User des Frameworks fühlt sich nicht so schlimm an. ;-)

dot hat geschrieben:Hängt davon ab, was du unter "technisch" verstehst. Es ist soweit korrekt als dass es korrektes C++ ist. Besonders toll ist es aber nicht... ;)

Ich mags ... Ich wäre nur beunruhigt, wenn es aufgrund des Thread-Themas nur "zufällig" funktionieren würde, weil etwas passiert, was eigentlich "garnicht gehen sollte". "Fachlich" (als Konsument meines eigenen Dogfoods) bin ich zufrieden.
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Jens H.
Establishment
 
Beiträge: 307
Registriert: 02.03.2011, 17:32
Wohnort: Esslingen/Dessau

Re: C++ Templates und virtuelle Methoden

Beitragvon Spiele Programmierer » 05.08.2016, 14:18

Ne, ich glaube, einer von uns beiden versteht den anderen gerade nicht (nicht zynisch gemeint).
Es geht darum, dass die Implementierungen, die auch der Collection arbeiten, nur das Interface (abstrakte Basisklasse unter TCollection, quasi ICollection) kennen und damit operieren. Es geht nicht darum, dass die Methoden "nur gleich heissen", dass ich sie besser verstehe.

Ne, das kann man auch mit einem gleichen Interface erreichen.
Der einzige Unterschied ist, dass die Polymorphie dann statisch und nicht dynamisch stattfindet. Weil C++ immer noch keine Concepts hat, wirkt das auf den ersten Blick etwas fragil, aber es funktioniert gut und hat den großen Vorteil das es eben statisch ist. Schau dir zum Beispiel alle Dinge in algorithm an. Die funktionieren auch mit jedem Container und das ganz ohne virtual call overhead. (Der pro Iterator schon extrem groß wäre)

Für diesen Zweck würde ich dir eine einfache "array_view" Klasse nahelegen.

Ja, sowas habe ich auch,

Warum nutzt es dann nicht auch für diesen Zweck? Was ist der Sinn?
Ich bin mir sogar ziemlich sicher, dass es in den aller meisten Fällen performanter wäre eine Hash Map für einen Call in einen Vector zu kopieren, anstatt durch die Hashmap mit virtual Calls zu gehen.

Nur Linked Lists kann man damit nicht darstellen: Allerdings die passen in dein "TBaseCollection" Interface eben so wenig und in der Regel lässt man eh besser die Finger von Linaked Lists.

Siehste ... ich kann das

Manchmal ist nicht unbedingt positiv bestimmte Dinge zu können.
Besonders wenn der allgemeine Fall so massiv leidet.

Mir ist nur wichtig, zu wissen, wenn ich hier "technisch kompletten Bullshit" gebaut hätte...

Nunja - es ist valides C++, ja.
Wenn dir darum geht, ob es sinnvoll ist, dann nein.

Wenn es nur dein Hobby ist, dann "darfst" du das natürlich machen.
Aber dann darfst du nicht gleichzeitig in einem Forum fragen und dich für die Meinung des "Erfinders der Sprache" interessieren. ;-)
Zuletzt geändert von Spiele Programmierer am 05.08.2016, 14:56, insgesamt 1-mal geändert.
Spiele Programmierer
Establishment
 
Beiträge: 341
Registriert: 23.01.2013, 16:55

Re: C++ Templates und virtuelle Methoden

Beitragvon dot » 05.08.2016, 14:26

Top-OR hat geschrieben:
dot hat geschrieben:Würd mich interessieren, wie genau du das machst. Ich seh jedenfalls keinen sinnvollen Weg, sequentielle und assoziative Container hinter ein gemeinsames Interface zu packen.

Echt nicht? Du kannst du nicht vorstellen, dass man für eine Menge von gleichen und diskreten Objekten eine Halbordnungsrelation definiert, denen diese Objekte genügen und anhand der du dann ein „>, „<“ oder ein „==“ ausführen kannst?

Ich kann mir nicht vorstellen, wie indizierter Zugriff auf einen durch eine solche Halbordnungsrelation definierten Container aussehen soll, denn eine der Eigenschaften einer Halbordnung ist ja gerade, dass es eben keine totale Ordnung gibt und sich so etwas wie ein Index gar nicht erst eindeutig definieren lässt. Abgesehen von der mangelnden Sinnhaftigkeit ist indizierter Zugriff für solche Container in der Regel zusätzlich auch nicht effizient implementierbar... ;)

Top-OR hat geschrieben:Da kannste doch alles nehmen, vorzusweise etwas, was den technischen Interna des Containers nahe steht und was deterministisches Verhalten an den Tag legt. Ich glaube, ich würde sogar auf einem Container Namens CAlterSchrankAufDemDachbodenMitKramsDrinne eine brauchbare Abzähllogik definieren, die sich deterministisch verhält. Wenn du die hast, ist auch operator[] kein Problem mehr. getCount() sowieso nicht.

Wenn du das kannst, kannst du sie auch abzählen und sie kommen bei jedem „Abzählvorgang“ in der gleichen Reihenfolge.

Außer ich füge ein neues Element in den Container ein oder entferne ein vorhandenes, denn dann werden alle dieser "Indices" zwangsweise ungültig, da sie nur für eine gegebene Menge an Elementen definierbar sind. Genau da liegt ja der Unterschied zwischen einem sequentiellen und einem assoziativen Container... ;)

Top-OR hat geschrieben:
dot hat geschrieben:Hängt davon ab, was du unter "technisch" verstehst. Es ist soweit korrekt als dass es korrektes C++ ist. Besonders toll ist es aber nicht... ;)

Ich mags ... Ich wäre nur beunruhigt, wenn es aufgrund des Thread-Themas nur "zufällig" funktionieren würde, weil etwas passiert, was eigentlich "garnicht gehen sollte". "Fachlich" (als Konsument meines eigenen Dogfoods) bin ich zufrieden.

Nun, dann kannst du beruhigt sein, undefiniertes Verhalten hast du mit obigem Konstrukt keines. Gutes C++ ist es aber definitiv nicht.
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1601
Registriert: 06.03.2004, 19:10

Re: C++ Templates und virtuelle Methoden

Beitragvon Top-OR » 05.08.2016, 15:04

Moment, moment, moment. Ich verstehe, ehrlich gesagt, immer weniger, was Ihr sagen wollt. (Nicht zynisch gemeint). Sehe ich das richtig, dass Ihr mir sagen wollt, dass:

1) ... die Idee, sequentiell durch z.B. Hashmaps oder Dachbodenschränke (zum Lesen und Value-Mamipulation) zu iterieren, blödsinnig ist?
oder
2) ... mein Ansatz, das mit einem gemeinsamen (Minimal-)Interface umzusetzen (welches ja nur zusätzlich zu den oft und am meisten genutzten containerspezifischen Zugriffsmethoden zur Verfügung steht), unglücklich ist und ich andere Sprachkonstrukte nutzen sollte?
oder
3) Lieber die fertigen Container verwenden sollte?
Zuletzt geändert von Top-OR am 05.08.2016, 15:43, insgesamt 1-mal geändert.
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Jens H.
Establishment
 
Beiträge: 307
Registriert: 02.03.2011, 17:32
Wohnort: Esslingen/Dessau

Re: C++ Templates und virtuelle Methoden

Beitragvon dot » 05.08.2016, 15:15

Top-OR hat geschrieben:Sehe ich das richtig, dass Ihr mir sagen wollt, dass:

1) Das die Idee, sequentiell durch z.B. Hashmaps oder Dachbodenschränke (zum Lesen und Value-Mamipulation) zu iterieren, blödsinnig ist?

Per Index auf Hashmaps oder Dachbodenschränke zugreifen ist sinnlos. Iterieren ist was Anderes und hat nix mit einem Index oder [] Operator zu tun... ;)

Top-OR hat geschrieben:2) Das mein Ansatz, das mit einem gemeinsamen (Minimal-)Interface umzusetzen (welches ja nur zusätzlich zu den oft und am meisten genutzten containerspezifischen Zugriffsmethoden zur Verfügung steht), unglücklich ist [...]

exactly

Top-OR hat geschrieben:3) Lieber die fertigen Container verwenden sollte?

Es geht nur darum, dass die fertigen Container nicht ohne Grund eben kein gemeinsames Interface für sequentielle und assoziative Container haben. Eben genau weil das keinen Sinn macht... ;)
Benutzeravatar
dot
Michael Kenzel
Establishment
 
Beiträge: 1601
Registriert: 06.03.2004, 19:10

Re: C++ Templates und virtuelle Methoden

Beitragvon Spiele Programmierer » 05.08.2016, 15:38

Es geht nur darum, dass die fertigen Container nicht ohne Grund eben kein gemeinsames Interface für sequentielle und assoziative Container haben.

Naja "empty", "size", "begin", "end" und ein paar andere haben sie in gewisser Weise schon gemeinsam.

Das in solche virtuellen Schnittstellen zu zwängen, halte ich trotzdem für sehr unsinnig.
Spiele Programmierer
Establishment
 
Beiträge: 341
Registriert: 23.01.2013, 16:55

Nächste

Zurück zu Algorithmen und Datenstrukturen

Wer ist online?

Mitglieder in diesem Forum: Yandex [Bot] und 1 Gast