Verweis auf gelöschte Funktion?
-
Du kannst
unique_ptr
nicht kopieren, daher wurde der Kopierkonstruktor alsdeleted
definiert (was der Compiler hier gelöscht nennt). Du musst stattdessen einfachnodes.emplace_back();
schreiben.
-
@Arcoth
Aber das müsste doch mit Move-Semantik gehen? Bei mir (g++ 4.8.1) kompiliert das einwandfrei.@happystudent
Welchen Compiler verwendest du?
-
icarus2 schrieb:
Bei mir kompiliert der Code. Hast du vielleicht einen Header vergessen?
Ne, eigentlich brauch man dafür ja nur <vector> und <memory>, oder? Die sind auf jeden Fall included...
icarus2 schrieb:
@happystudent
Welchen Compiler verwendest du?Visual Studio 2013 Professional.
Arcoth schrieb:
Du kannst
unique_ptr
nicht kopieren, daher wurde der Kopierkonstruktor alsdeleted
definiert (was der Compiler hier gelöscht nennt). Du musst stattdessen einfachnodes.emplace_back();
schreiben.
Hm, das führt bei mir zu genau der gleichen Fehlermeldung...
-
Aber das müsste doch mit Move-Semantik gehen?
Genau, aber ich dachte anfangs, das wäre vielleicht ein Bug von VC++. Wäre ja plausibel.
@TE: Entschuldige - natürlich sollte es nicht der Kopierkonstruktor sein, schließlich hast du ja schon C++11... was genau ist denn die Fehlermeldung? Poste sie komplett.
-
Bitteschön:
1>------ Erstellen gestartet: Projekt: Graph, Konfiguration: Debug Win32 ------
1> Graph.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(592): error C2280: 'std::unique_ptr<node,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : Es wurde versucht, auf eine gelöschte Funktion zu verweisen
1> with
1> [
1> _Ty=node
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486): Siehe Deklaration von 'std::unique_ptr<node,std::default_delete<_Ty>>::unique_ptr'
1> with
1> [
1> _Ty=node
1> ]
1> Diese Diagnose trat in der vom Compiler generierten Funktion "vertex::vertex(const vertex &)" auf.
-
Diese Diagnose trat in der vom Compiler generierten Funktion "vertex::vertex(const vertex &)" auf.
Das ist ein Bug, weil der Compiler hier keine Fehlermeldung geben sollte, sondern die Funktion schlicht als
deleted
definieren sollte. (Ich nehme an, dassvertex
der Klassevertice
im OP entspricht)
-
Arcoth schrieb:
(Ich nehme an, dass
vertex
der Klassevertice
im OP entspricht)Ja stimmt, sorry. Hatte ich schon ausgebessert ^^
Arcoth schrieb:
Das ist ein Bug, weil der Compiler hier keine Fehlermeldung geben sollte, sondern die Funktion schlicht als
deleted
definieren sollte.Ok, was kann ich dann machen um das zu lösen? Ich hätte halt gerne für jeden Knoten ne Liste (bzw. vector) mit Pointern auf dessen Nachbarn, das sollte ja in VS auch möglich sein?
-
Insbesondere, da Icarus2 kein Problem mit dem code hat, vermute ich mal du legst irgendwo (potentiell) eine Kopie von "nodes" an, damit braucht node einen copy-ctor, damit braucht vertice einen copy-ctor, damit braucht der unique_ptr einen copy-ctor. Und das geht nicht.
Die Frage ist, wo du diese Kopie anlegst, und ich Zweifel irgendwie daran, dass es bei emplace_back() ist. Falls es doch so sein sollte, wohl doch ein bug.
Mach mal den node copy-ctor auf delete, damit du findest wo er den aufrufen will.
-
Ok, was kann ich dann machen um das zu lösen?
Das sieht problematisch aus; erstmal würde ich bei VC++ gucken, ob es bereits einen Bug-Report gibt (ggf. muss einer geschrieben werden).
Hilft es, wenn du den Kopierkonstruktor höchstpersönlich als
deleted
definierst? Also wenn du in der Klassendefinition von vertexvertex( vertex const& ) = delete;
hinzufügst?
-
kleiner Troll schrieb:
Insbesondere, da Icarus2 kein Problem mit dem code hat, vermute ich mal du legst irgendwo (potentiell) eine Kopie von "nodes" an, damit braucht node einen copy-ctor, damit braucht vertice einen copy-ctor, damit braucht der unique_ptr einen copy-ctor. Und das geht nicht.
Also ich benutze momentan wirklich nur den geposteten Code, soweit ich das beurteilen kann erstelle ich keine Kopie...
Arcoth schrieb:
Hilft es, wenn du den Kopierkonstruktor höchstpersönlich als
deleted
definierst? Also wenn du in der Klassendefinition von vertexvertex( vertex const& ) = delete;
hinzufügst?
Leider nicht. Das hier ist jetzt mein aktueller Code:
struct node; struct vertex { vertex(vertex const&) = delete; std::unique_ptr<node> neighbours; double weight; }; struct node { std::vector<vertex> vertices; }; class weighted_graph { public: weighted_graph() { nodes.emplace_back(); } std::vector<node> nodes; }; int _tmain(int argc, _TCHAR* argv[]) { weighted_graph wg; return 0; }
und das die zugehörige Fehlermeldung:
1>------ Erstellen gestartet: Projekt: Graph, Konfiguration: Debug Win32 ------
1> Graph.cpp
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(593): error C2280: 'vertex::vertex(const vertex &)' : Es wurde versucht, auf eine gelöschte Funktion zu verweisen
1> c:\users\my_user_name\documents\visual studio 2013\projects\graph\graph\graph.cpp(60): Siehe Deklaration von 'vertex::vertex'
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(592): Bei der Kompilierung der Klassen-template der void std::allocator<_Ty>::construct(_Ty *,const _Ty &)-Memberfunktion
1> with
1> [
1> _Ty=vertex
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(723): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void std::allocator<_Ty>::construct(_Ty *,const _Ty &)".
1> with
1> [
1> _Ty=vertex
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\type_traits(572): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "std::allocator<_Ty>".
1> with
1> [
1> _Ty=vertex
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector(650): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "std::is_empty<_Alloc>".
1> with
1> [
1> _Alloc=std::allocator<vertex>
1> ]
1> c:\users\my_user_name\documents\visual studio 2013\projects\graph\graph\graph.cpp(67): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "std::vector<vertex,std::allocator<_Ty>>".
1> with
1> [
1> _Ty=vertex
1> ]Arcoth schrieb:
Das sieht problematisch aus; erstmal würde ich bei VC++ gucken, ob es bereits einen Bug-Report gibt (ggf. muss einer geschrieben werden).
Oje, das dauert ja dann wahrscheinlich Monate oder Jahre bis das dann auch wirklich gefixed wird
Kann man da nichts anderes machen? Also nen alternativen Ansatz oder so?
-
Ich sekundiere mal "kleiner Troll":
Das ist nicht der ganze Code.
Zuviel gekürzt, falsch gekürzt.Lies das:Den richtigen Code posten: reduziertes compilierbares Beispiel und komm mit einem kompletten Beispiel wieder.
-
Furble Wurble schrieb:
Ich sekundiere mal "kleiner Troll":
Das ist nicht der ganze Code.
Zuviel gekürzt, falsch gekürzt.Lies das:Den richtigen Code posten: reduziertes compilierbares Beispiel und komm mit einem kompletten Beispiel wieder.
Das ist mein komplettes Beispiel
Das einzige was fehlt ist das
#include <vector>
und#include <memory>
, aber das denke ich kriegt man auch so hin.Wie kommst du denn bitte darauf dass das nicht der komplette Code sein soll? Btw ist es leicht wiedersprüchlich ein compilierbares Beispiel zu fordern, welches einen Compile-Fehler demonstrieren soll, nur so am Rande.
-
Furble Wurble schrieb:
Ich sekundiere mal "kleiner Troll":
Das ist nicht der ganze Code.
Zuviel gekürzt, falsch gekürzt.Wenn man die fehlenden includes einbaut produziert der Code den Fehler
-
Was ist der Unterschied zwischen vertex und node? Heisst doch beides Knoten.
neighbours als unique_ptr sieht für mich merkwürdig aus. Ich würde entweder direkt node erwarten oder einen geteilten (also nicht unique) Pointer.
-
happystudent schrieb:
Wie kommst du denn bitte darauf dass das nicht der komplette Code sein soll?
Mein Posting überschnitt sich mit Deinem.
Das ist doch das komplette Beispiel, das ich sehen wollte.
-
manni66 schrieb:
Was ist der Unterschied zwischen vertex und node? Heisst doch beides Knoten.
Hm, ja vertex sollte wahrscheinlich eher "edge" heißen. Der Unterschied ist halt, das eine ist der Knoten, das andere die (gewichtete) Verbindung von zwei Knoten.
manni66 schrieb:
neighbours als unique_ptr sieht für mich merkwürdig aus. Ich würde entweder direkt node erwarten oder einen geteilten (also nicht unique) Pointer.
Ok, also mit
shared_pointer
dann? Werd ich gleich mal ausprobieren.Edit:
Furble Wurble schrieb:
Mein Posting überschnitt sich mit Deinem.
Das ist doch das komplette Beispiel, das ich sehen wollte.Ok, alles klar, dann Entschuldigung
-
happystudent schrieb:
manni66 schrieb:
Was ist der Unterschied zwischen vertex und node? Heisst doch beides Knoten.
Hm, ja vertex sollte wahrscheinlich eher "edge" heißen. Der Unterschied ist halt, das eine ist der Knoten, das andere die (gewichtete) Verbindung von zwei Knoten.
Du solltest dir wohl erst mal über die Modellierung klar werden. Ein Kante verbindet zwei Knoten. Ein Knoten kann durch mehrere Kanten mit anderen Knoten verbunden werden.
happystudent schrieb:
manni66 schrieb:
neighbours als unique_ptr sieht für mich merkwürdig aus. Ich würde entweder direkt node erwarten oder einen geteilten (also nicht unique) Pointer.
Ok, also mit
shared_pointer
dann? Werd ich gleich mal ausprobieren.Eher nicht. Wenn du dabei einen Zyklus einbaust, kannst du nichts mehr löschen.
-
Der Vollstänfigkeit halber: so geht's
#include <memory> #include <vector> struct node; struct vertex { vertex(vertex &&v) : neighbours(std::move(v.neighbours)), weight(v.weight) {} vertex() = default; std::unique_ptr<node> neighbours; double weight; }; struct node { std::vector<vertex> vertices; node(node &&v) : vertices( std::move(v.vertices)) {} node() = default; }; class weighted_graph { public: weighted_graph() { nodes.emplace_back(); } std::vector<node> nodes; }; int main() { weighted_graph wg; return 0; }
Der Moveconstructor muss zu Fuß implementiert werden!
-
manni66 schrieb:
Der Vollstänfigkeit halber: so geht's
Der Moveconstructor muss zu Fuß implementiert werden!
Cool, danke, das kompiliert jetzt
manni66 schrieb:
Du solltest dir wohl erst mal über die Modellierung klar werden. Ein Kante verbindet zwei Knoten. Ein Knoten kann durch mehrere Kanten mit anderen Knoten verbunden werden.
Ja, also da es sich dabei um einen gerichteten Graphen handlen soll müsste das aber so passen denke ich, da man ja nur zu den Knoten laufen können soll, auf die die aktuelle Kante zeigt.
-
manni66 schrieb:
Ein Kante verbindet zwei Knoten.
Vielleicht will er auch einen Hypergraphen implementieren