Hallo,
ich beschäftige mich gerade etwas mit C++, da ich einige Funktionen der
CGAL bzw. Boost Bibliothek verwenden möchte...
Eine der Sachen, die ich nicht durchschaue, und zu der mir jetzt auch
kein Stichwort für Google einfällt:
http://www.boost.org/doc/libs/1_52_0/doc/html/heap/concepts.html#heap.concepts.basic
Fast ganz unten auf der Seite
>Note that handles can be stored inside the value_type:> (*handle).handle = handle; // store handle in node
handle ist doch kein Zeiger, sondern eher ein opaker Datentyp. Was ist
dann (*handle).handle bzw. etwas weiter unten dieses
>*t3 = 4;
Ist das ein Zugriff auf spezielle öffentliche Bereiche der Handle
Datenstruktur? Und die noch wichtigere Frage: Was hat man davon, dass
man wie hier handle in handle speichert? Sinn würde es machen, wenn man
von struct heap_data irgendwie wieder an handle herankäme, aber das sehe
ich nicht.
Viel findet man mit Suchmaschienen leider nicht zu den Boost
Heap-Datenstrukturen, und die dortigen Beispiele speichern leider nur
einfache int-Werte statt strukturierter Typen ein. Und ein ganzes C++
Buch möchte ich jetzt nicht durcharbeiten -- ich will lediglich ein paar
kleine Routinen von Ruby aus nutzbar machen, was auch schon teilweise
funktioniert.
Stefan schrieb:> Sinn würde es machen, wenn man> von struct heap_data irgendwie wieder an handle herankäme
Ah!
>struct heap_data>{> fibonacci_heap<heap_data>::handle_type handle;
Den Eintrag habe ich doch glatt die ganze Zeit übersehen. Dann komme ich
von heap_data tatsächlich an handle heran, so macht das Sinn.
Bleibt nur noch die Frage was eigentlich
>*t3 = 4;>(*handle).handle =
bedeutet. Wenn t3 ein Pointer wäre, würde man den Ort, wo er hin zeigt,
mit dem Wert 4 überschreiben. Sollte es so sein, dass hier der erste
Speicherplatz von handle mit eben diesem Wert beschrieben wird?
Glaube ich fast. Aber was ist
>(*handle).handle =
Ja -- nicht, dass ich das schon wirklich verstehe, aber immerhin
funktioniert das bei mir soweit.
Ein (hoffentlich) letztes Problem hätte ich noch: Wie kann ich die
Struktur PriorityQueue um eine int Variable erweitern, auf die ich
zugreifen kann?
Ich habe mich ja weitgehend an dem Beispiel interface.cpp
http://www.ssalewski.de/tmp/interface.cpp
orientiert, da steht dann etwa
>template <typename PriorityQueue>>void iterator_interface(void)>{>PriorityQueue pq;>pq.push(2);
Was ich nun haben möchte:
pq.my_int_stefan = -1
cout << pq.my_int_stefan
Ich hoffe mal, es ist klar was ich meine -- wenn nicht werde ich meinen
eigenen Qulelltext online stellen, wenn ich ihn etwas aufgeräumt habe.
Wie man eine Klasse erweitert weiß ich schon in etwa, nur mit diesen
Funktions-Templates verheddere ich mich irgendwie. (Und wenn sich wer
fragt, warum: Ich möchte die PriorityQueue von Ruby aus ohne
Neukompilierung als Min- oder Max-Queue benutzen können, daher muss eine
Variable mit ihr verknüpft sein, so dass ich dann beim Einspeichern und
Ausgeben bei Bedarf das Vorzeichen der Schlüssel invertieren kann.
stefan@AMD64X2 ~/newboosttest $ make ttt
g++ ttt.cpp -o ttt
ttt.cpp: In function 'void basic_interface() [with PriorityQueue =
boost::heap::fibonacci_heap<int>]':
ttt.cpp:50:39: instantiated from here
ttt.cpp:33:2: error: 'class boost::heap::fibonacci_heap<int>' has no
member named 'x'
make: *** [ttt] Error 1
Was soll mir das sagen?
Nun gut, da Herr Buchegger wohl schon im Weihnachtsurlaub ist, habe ich
versucht selbst etwas hinzufrikeln:
[c]
#include <iostream>
#include <iomanip>
#include <boost/heap/fibonacci_heap.hpp>
using std::cout;
using std::endl;
using namespace boost::heap;
class XQ : public boost::heap::fibonacci_heap<int>
{
public:
int x;
};
typedef XQ XXX;
template <typename XXX>
void basic_interface(void)
{
XQ pq;
pq.x = -1;
pq.push(2);
cout << pq.top()*pq.x << endl;
}
int main(void)
{
//XQ q;
using boost::heap::fibonacci_heap;
basic_interface<fibonacci_heap<int> >();
return 0;
}
[\c]
stefan@AMD64X2 ~/newboosttest $ ./ttt
-2
Das ist in etwa das, was ich wollte -- hoffe ich jedenfalls.
Stefan Salewski schrieb:> Das ist in etwa das, was ich wollte -- hoffe ich jedenfalls.
Es ergibt leider nicht sehr viel Sinn...
> typedef XQ XXX;
Dieses typedef wird nirgendwo benutzt.
> template <typename XXX>
Das Template-Argument wird ebenfalls nirgendwo benutzt, und somit hat es
keinerlei Effekt, daß du hier überhaupt ein Template verwendest. Das XXX
hier hat übrigens keinen Zusammenhang zum XXX oben.
Den selben Effekt hätte es, wenn du stattdessen schreibst:
@Rolf Magnus
Ah, Dich gibt es hier also auch noch, neben Karl Heinz B. als C++
Experten...
Was Du schreibst habe ich dann gestern Abend auch noch bemerkt --
wichtig war mir zunächst, irgendwie dieses Template-Gewirr zu bändigen.
Für mich war der wesentliche Trick
Dann habe ich eine ganz harmlose C++ Klasse mit meinem Struct heap_data
als Knoten der Vorrang-Schlange und kann etwa schreiben
1
XPQ*new_fqueue(void)
2
{
3
XPQ*pq=newXPQ;
4
pq->x=77;// Test
5
cout<<pq->x<<endl;// Test
6
returnpq;
7
}
Dass man so einfach aus einer Klasse mit Template eine erweiterte Klasse
ohne Template machen kann hatte ich nicht gewusst und auch nirgendwo
gefunden, letztlich dann erraten.
Gruß
Stefan
Welchen Sinn machen da die Hilfsvariablen begin und end -- eigentlich
doch keinen, wenn man die Queue wahrend der Iteration nicht ändert, und
das darf man doch wohl eh nicht?
Also warum nicht einfach
Stefan Salewski schrieb:> Welchen Sinn machen da die Hilfsvariablen begin und end -- eigentlich> doch keinen, wenn man die Queue wahrend der Iteration nicht ändert, und> das darf man doch wohl eh nicht?
Eigentlich braucht man sie nicht. Bei end könnte man sich noch
vorstellen, daß der Schreiber des Programms vielleicht vermeiden wollte,
daß die Funktion end() und die Erzeugung des entsprechenden Iterators
bei jedem Schleifendurchlauf aufs Neue gemacht wird.
> Also warum nicht einfach> for (typename PriorityQueue::iterator it = pq.begin(); it != pq.end();> ++it)
Geht genauso. Ich hätte das auch so geschrieben.